[英]scala implicit class method type mismatch in reduce vs non-implicit method with function currying
关于隐式类的东西,混淆reduce()。 在隐式类内部时,编译器会在reduce()第二个参数上抱怨。 但是当相同的代码在非隐式方法中时,它编译并正常工作。
我对隐含类缺少什么?
object ImpliCurri {
implicit class MySeq[Int](val l: Seq[Int]) {
//not compiling
final def mapSum(f:Int=>Int):Int = {
l.map(x=>f(x)).reduce(_+_)
//compile error on reduce: Type mismatch. Expected String, fount Int
}
}
// works fine
def mySum(l:Seq[Int], f:Int=>Int):Int = {
l.map(x=>f(x)).reduce(_+_)
// compiles and works no issues
}
}
你需要摆脱类型参数Int
。 Int
中所隐含的类的情况下,实际上不是类型Int
,而是它是一个的阴影的名字自由类型参数Int
。
隐藏编译器错误的原因是编译器从lambda _ + _
推断类型Any
(因为类型参数可能是任何东西),并假设+
将来自类型为Any
的toString
。 如果在类声明中用T
替换Int
,您将看到错误是相同的。
这将有效:
implicit class MySeq(val l: Seq[Int]) {
final def mapSum(f: Int => Int): Int = {
l.map(x => f(x)).reduce(_ + _)
}
}
它实际上与implicits没有任何关系。 如果它只是一个普通的class
你会得到同样的错误。
原因是你已经声明了一个泛型类型: MySeq[Int]
恰好被称为Int
。 所以当你说f: Int => Int
你会想“哦,那是一个整数”,编译器认为,“哦,这意味着你可以在那里填写任何类型!”。 (将所有的Int
替换为A
,它的工作方式相同。)
现在编译器处于绑定状态。 什么+
你可以适用于任何类型的? 好吧,你可以将任何东西转换为String
, +
在String
上定义。 因此,当编译器意识到此方法不起作用时,您会收到一个非常误导性的错误消息。
只需删除[Int]
,你的所有Int
实际意味着你认为它们的意思,隐式类版本将正常工作。
用MySeq[Int](val l: Seq[Int])
替换MySeq[Int](val l: Seq[Int])
MySeq(val l: Seq[Int])
。
编译器消息的说明:
MySeq[Int]
部分为名为Int
MySeq
类定义一个抽象类型参数,它是(自动) Any
的子类并scala.Int
实际的scala.Int
。 然后编译器尝试调用Any
实例的+
方法。 它看到一个隐式类scala.Predef.any2stringadd
的声明,它有一个带有签名def +(other: String): String
,因此编译器认为第二个参数+
应该是一个String
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.