2016-05-13 41 views
1

可以通過函數做match-case嗎? 我想爲不同類型的函數定義一個行爲。說我有以下幾種可能:Scala:匹配通用函數的案例

  • f: T => Int
  • f: T => String
  • f: T => Lis[Int]
  • f: T => Boolean
  • f: T => Double
  • ...

,併爲每個這些O我有一個功能;例如用於Int輸出: def doThisForInt(f: T => Int) = { ... } 這對於Boolean輸出: ' DEF doThisForBoolean(F:T =>布爾)= {...}

所以,現在假設一個函數定義給出:val f = (input: T) => true。我們應該選擇相應的案例f: T => Boolean

請注意,所有這些功能在輸出類型上都不相同。另外,給定f可以得到這個函數的輸出類型嗎?

+5

你的用例是什麼?聽起來類型類會更適合這種情況,因爲巨大的匹配/情況是代碼味道。 –

+0

就像爲這些情況中的每一個定義類型一樣?像'f:T => Int',一個用於'f:T => Double'等等? – Daniel

+1

您想要使用匹配的方法的簽名是什麼?它不會接受'T => Int'因爲你希望它是通用的,對嗎?例如:'def doSomething [T,R](f:T => R):??? = ???'?應該返回什麼? –

回答

4

TypeTags是你在找什麼:

import scala.reflect.runtime.universe._ 

def doThisForInt(f: T => Int) = ??? 

def printType[R: TypeTag](f: T => R) = typeOf[R] match { 
    case t if t =:= typeOf[Int] => 
    val toInt: (T) => Int = f.asInstanceOf[T => Int] 
    doThisForInt(toInt) 
    case t if t =:= typeOf[Double] => 
    // ... 
    case t if t =:= typeOf[List[Int]] => 
    // ... 
} 

printType((x: T) => 1) // int 
printType((x: T) => 2.0) // double 
printType((x: T) => List(2)) // list 

正如你所看到的,這是可能的,但不是很優雅和反對good practices

instanceOf檢查的鏈通常可以用虛擬方法替代(請參閱example),並且函數的結果類型可能是類型參數。如果不知道更多關於用例的上下文,很難提供更多的建議。

相關問題