请考虑以下代码段:
def fun1(x:T): String = // something here
var grandFun = {
t: T => Map('key1 -> fun1(t))
}
问题是,是否可以以编程方式向grandFun
内的地图添加新功能?
基本上,填写以下功能:
def addFunToMyGrandFun(fun: T => String): Unit = {
// add fun go the `grandFun`
}
这样给:
def fun2(x:T): String = // something here
运行addFunToMyGrandFun(fun2)
后,grandFun
会更新为以下内容:
var grandFun = {
t: T => Map('key1 -> fun1(t), 'key2 -> fun2(t))
}
答案 0 :(得分:3)
您可以在函数外部定义一个仅存储函数的映射。然后,您可以在函数中使用此贴图,并在地图中应用函数以获取所需的贴图。
如果您使用mutable.Map
,则可以向地图添加新功能。在toMap
上拨打mutable.Map
会返回immutable.Map
。
import scala.collection.mutable.{Map => MutableMap}
val functionMap = MutableMap.empty[Symbol, T => String]
val grandFun = (t: T) => functionMap.mapValues(f => f(t)).toMap
例如,如果T
是Int
:
val yourMap = MutableMap.empty[Symbol, Int => String]
val grandFun = (n: Int) => functionMap.mapValues(f => f(n)).toMap
yourMap += 'key1 -> ((_: Int).toString)
grandFun(5) // Map('key1 -> 5)
yourMap += 'key2 -> ((_: Int).toString * 5)
grandFun(10) // Map('key2 -> 55555, 'key1 -> 5)
答案 1 :(得分:2)
如果您的密钥只是String
而不是符号,那么我认为类似下面的类应该封装您的意图:
case class GrandFun[T,R](funs: Map[String, Function1[T,R]], count: Int) {
def addFun(fun: T => R) = {
val key = s"key$count"
GrandFun(funs + (key -> fun), count + 1)
}
def apply(t: T) = funs mapValues { fun => fun(t) }
}
object GrandFun {
def apply[T,R](): GrandFun[T,R] = new GrandFun(Map.empty[String,Function1[T,R]], 0)
}
使用示例:
scala> val gf = GrandFun[Int, String]
gf: GrandFun[Int,String] = GrandFun(Map(),0)
scala> val gf1 = gf.addFun(fun1)
gf1: GrandFun[Int,String] = GrandFun(Map(key0 -> <function1>),1)
scala> def fun1(t: Int): String = t.toString
fun1: (t: Int)String
scala> def fun2(t: Int): String = (t+2).toString
fun2: (t: Int)String
scala> val gf1 = gf.addFun(fun1)
gf1: GrandFun[Int,String] = GrandFun(Map(key0 -> <function1>),1)
scala> val gf2 = gf1.addFun(fun2)
gf2: GrandFun[Int,String] = GrandFun(Map(key0 -> <function1>, key1 -> <function1
>),2)
scala> gf2(4)
res7: scala.collection.immutable.Map[String,String] = Map(key0 -> 4, key1 -> 6)
请注意,我选择将GrandFun
设为不可变,但您也可以使用可变形式,例如:
class GrandFun[T,R] {
private var funs = Map[String, Function1[T,R]]()
private var count = 1
def addFun(fun: T => R) {
val key = s"key$count"
count += 1
funs = funs + (key -> fun)
}
def apply(t: T) = funs mapValues { fun => fun(t) }
}