为什么scala不能从泛型类型参数中推断出类型?
假设这个函数
def func[A](data: List[A], mapper: A => String) = {
data.map(item => mapper(item))
}
为什么这段代码不能编译:
val list = List(1, 2, 3)
func(list, a => a.toString)
但是这个确实如此:
val list = List(1, 2, 3)
func[Int](list, a => a.toString)
要么
val list = List(1, 2, 3)
func(list, (a: Int) => a.toString)
虽然a
类型可以从列表中可以推断这是List
的Int
。 为什么scala不能在这里推断这种类型?
有没有其他方法?
还有另一种方式! 它也恰好为一些很好的合成糖做出了贡献:
def func[A](data: List[A])(mapper: A => String) = data map mapper
这看起来像:
func(myList){
case Left(one) => one
case Right(_) => default
}
您无法按照您期望的方式获取类型信息的原因在于,Scala中的类型信息保持不变。 在其他系统中,类型信息是已知的,并根据定义的用途进行推导。 你有时必须解决这些限制,但同时,在这种情况下,你可以开始使用类似于你自己定义的控制结构的东西。
所以...
func[Int]( //I've just told the typer what the information is and it can flow to the right.
func(list //the typer has to deduce the type and without a guide can not figure out what a => a.toString should be
这也是一个老问题,你可以在这里看到SI-4773。
在评论中对Q的回应 :
如果你想有一个Seq[A => B]
那么我会做类似的事情
func[A, B](data: List[A])(actions: A => B*) = actions map {
data map
}
这是使用可变参数(转换为WrappedArray
,因此map
)接受任何命令列表,以便您可以传递是
func(list)(_.name, _.age, _.sex, _.stalker)
至于拉出并匹配你所传递的内容:
func[A, B](data: List[A])(actions: (String, A => B)*) = actions map {
case (name, f) => (name, data map f)
}
其中你正在使用case
语句来模式匹配并提取元组。
上一篇: Why scala doesn't infer type from generic type parameters?