将Int减少为单个Int工作正常:
val input = List(3, 5, 7, 11)
def op(total: Int, cur: Int) = total + cur//> op: (total: Int, cur: Int)Int
input reduce op
但是当我尝试连接String的时候:
def op(total: String, cur: String) = (total + cur) //> op: (total: Int, cur: Int)Int
val input = List(3, 5, 7, 11)
input reduce op
导致编译器错误:类型不匹配; found:(String,String)=>需要的字符串:(任何,任何)=>任何
String不是Any类型吗?
答案 0 :(得分:1)
您无法将input
集合(Int
s)的元素传递给接受String
的函数。
请参阅reduce
方法的声明:
def reduce[A1 >: A](op: (A1, A1) => A1): A1
A
这里是元素的类型(在您的情况下A
是Int
)。
A1
应该是A
的超类型。
Any
是Int
的超类型,但String
不是Int
的超类型。
实际上编译器错误不完全正确,需要任何函数(A1, A1) => A1
,A1
是A
的超类型(在您的情况下A
是Int
)。
另请注意,(String, String) => String
不是(Any, Any) => Any
的子类型,因此您无法在需要(String, String) => String
的情况下使用(Any, Any) => Any
。
答案 1 :(得分:1)
你有一个功能,使用字符串和回溯字符串,你尝试用整数提供它。您需要某种从字符串到整数的转换(显式或隐式)。
编译器知道为reduce提供的函数必须接受具有一种类型的每个值的对(两个元素具有相同的类型)并返回相同类型的一个值。当使用Integers并期望字符串时,此类型只能是Any类型。
但您的功能属于 (String, String) => String
类型。这不能映射到(Any, Any) => Any
。返回值不是问题,因为String总是可以转换为Any。但是参数是一个问题:并非每个Any都可以总是被转换为String。
将您的值转换为字符串,例如
val input = List(3, 5, 7, 11).map(_.toString)
或添加隐式转换器函数
implicit def lint2lstr : List[Int] => List[String] = _.map(_.toString)
然后,当您定义
时,编译器将自动插入转换val input : List[String] = List(3, 5, 7, 11)
答案 2 :(得分:0)
input
此处的类型为List[Int]
List的reduce
方法具有以下声明
def reduce[A1 >: A](op: (A1, A1) => A1): A1
基本上,这说明reduce
List[A]
接受(A1, A1) => A1
类型的运算符并返回A1
类型,其中A1
是超类型A
。在您的情况下,A1
必须是Int
或其超类型。
这是因为reduce通过在项目上连续应用运算符来工作。即。前两个项的运算符的结果与下一个项一起使用。这意味着操作符函数声明应该使得相同的函数可以接受它产生的结果以及列表中的项目。