减少一个字符串导致编译时错误?

时间:2014-01-09 10:36:50

标签: scala

将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类型吗?

3 个答案:

答案 0 :(得分:1)

您无法将input集合(Int s)的元素传递给接受String的函数。

请参阅reduce方法的声明:

def reduce[A1 >: A](op: (A1, A1) => A1): A1

A这里是元素的类型(在您的情况下AInt)。

A1应该是A的超类型。

AnyInt的超类型,但String不是Int的超类型。

实际上编译器错误不完全正确,需要任何函数(A1, A1) => A1A1A的超类型(在您的情况下AInt )。

另请注意,(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通过在项目上连续应用运算符来工作。即。前两个项的运算符的结果与下一个项一起使用。这意味着操作符函数声明应该使得相同的函数可以接受它产生的结果以及列表中的项目。