【发布时间】:2015-06-27 13:20:51
【问题描述】:
以下 Scala 代码有效:
object ReducerTestMain extends App {
type MapOutput = KeyVal[String, Int]
def mapFun(s:String): MapOutput = KeyVal(s, 1)
val red = new ReducerComponent[String, Int]((a: Int, b: Int) => a + b)
val data = List[String]("a", "b", "c", "b", "c", "b")
data foreach {s => red(mapFun(s))}
println(red.mem)
// OUTPUT: Map(a -> 1, b -> 3, c -> 2)
}
class ReducerComponent[K, V](f: (V, V) => V) {
var mem = Map[K, V]()
def apply(kv: KeyVal[K, V]) = {
val KeyVal(k, v) = kv
mem += (k -> (if (mem contains k) f(mem(k), v) else v))
}
}
case class KeyVal[K, V](key: K, value:V)
我的问题是我想像这样实例化ReducerComponent:
val red = new ReducerComponent[MapOutput, Int]((a: Int, b: Int) => a + b)
甚至更好:
val red = new ReducerComponent[MapOutput](_ + _)
这意味着很多事情:
- 我想检查
MapOutput的类型是否为KeyVal[K, C], - 我想检查
C是否与f中使用的类型相同, - 我还需要“提取”
K以实例化mem,并从apply中检查参数。
要问的很多吗? :) 我想写类似的东西
class ReducerComponent[KeyVal[K,V]](f: (V, V) => V) {...}
到我将实例化ReducerComponent 时,我所拥有的只有f 和MapOutput,所以推断V 是可以的。但是我只有KeyVal[K,V]作为类的类型参数,它可以不同于KeyVal[_,_]。
如果您了解类型推断的工作原理,我知道我的问题可能很疯狂,但我不知道!而且我什至不知道什么是继续的好方法——除了在我的高级代码中一直进行显式类型声明。我应该改变所有的架构吗?
【问题讨论】:
标签: scala type-inference type-parameter scala-generics