2016-04-21 74 views
1

假設我想存儲一個Map[String, Function1],其中Function1的參數和返回類型可以變化。我會如何去儲存Function1[String, String]Function1[Int, Int]在同一個地圖。Scala函數1通用參數和返回類型

我試過Function1[AnyRef, AnyRef],但Function1[String, String]不是Function1[AnyRef, AnyRef],所以無法編譯。

+0

我不認爲你可以以類型安全的方式做到這一點 –

+0

你可以存儲一個ADT,即'密封性狀MyFn |案例類Fn1(f:Int => Int)擴展了MyFn | case class Fn2(f:String => String)'?然後,在'Map#get'結果上進行模式匹配,即'Option [MyFn]'。 –

+0

編譯的類型是'Nothing => Any',它會接受任何函數。請參閱'val f:Nothing => Any =(a:String)=> a.toInt' –

回答

3

如果你只有兩種可能的值類型,你可以在Either包裹值:

val m = Map[String, Either[Int => Int, String => String]]() 

如果你想存儲兩個以上不同類型,創建您自己的包裝,或者使用類似Coproduct from shapeless

2

這看起來像你之後?

scala> val m = Map[String, Function1[_,_]]() 
m: scala.collection.immutable.Map[String,Function1[_, _]] = Map() 

scala> val f1 = (i:Int) => i*3 
f1: Int => Int = <function1> 

scala> val f2 = (b: Boolean) => if (b) "YES" else "NO" 
f2: Boolean => String = <function1> 

scala> m + ("xcx" -> f2) + ("rtr" -> f1) 
res59: scala.collection.immutable.Map[String,Function1[_, _]] = Map(xcx -> <function1>, rtr -> <function1>) 
+1

我不瘦,你可以在從地圖中檢索它們之後實際使用這些函數 – pedrofurla

+2

檢索到的函數是可用的,但你必須施放它,'m(「rtr」)。asInstanceOf [Function1 [Int,Int]](4)',這是一個很好的跡象表明你需要重新考慮這種方法。 – jwvh

+0

這個目標是爲一個類的字段保存一堆轉換函數。因此,給定POJO(或Scala等價類)的列表,獲取對象類的字段(例如val someString,val someInt等),並應用可返回任何其他類型的給定函數(例如,將someString轉換爲aLong )通過使用反射的所述字段的名稱,針對POJO列表中的每個項目。 –