OoS*_*OoS 2 types scala type-mismatch type-parameter
class TestClass[T](val x: T) { def +(other: TestClass[T]) = x + other.x }
这个定义给了我以下编译错误:
错误:类型不匹配;
found:T
required:String
def +(其他:TestClass [T])= x + other.x
是不是可以使用Int或Double作为类型参数并在Scala中使用添加?
首先,错误消息具有误导性.scalac试图找到一个+价值方法x.这在类型上不存在T,可以是任何类型.这称为无界类型参数.所以它试图应用隐式视图.Predef.any2stringadd符合条件.
您可以禁用此隐式转换,并查看真正的错误:
~/code/scratch: cat plus.scala
import Predef.{any2stringadd => _, _}
class TestClass[T](val x: T) {
def +(other: TestClass[T]) = x + other.x
}
~/code/scratch: scalac plus.scala
plus.scala:4: error: value + is not a member of type parameter T
def +(other: TestClass[T]) = x + other.x
^
one error found
Run Code Online (Sandbox Code Playgroud)
在C++中,类型检查在每个调用站点提供type参数后完成.所以这种代码风格可行.在Scala中,泛型方法必须在其定义上进行类型检查,仅基于抽象类型的边界.
正如VonC所建议的那样,您可能希望在type参数上提供上下文绑定,T以约束if是否具有相应的Numerictrait 实例的类型.
class TestClass[T: Numeric](val x: T) {
def +(other: TestClass[T]): T = {
val num = implicitly[Numeric[T]]
import num._
x + other.x
}
}
Run Code Online (Sandbox Code Playgroud)
以下是显示所有隐含的内容:
class TestClass[T]{
implicit <paramaccessor> private[this] val evidence$1: Numeric[T] = _;
def this(x: T)(implicit evidence$1: Numeric[T]): TestClass[T] = {
TestClass.super.this();
()
};
def +(other: TestClass[T]): T = {
val num: Numeric[T] = scala.Predef.implicitly[Numeric[T]](TestClass.this.evidence$1);
import num._;
num.mkNumericOps(TestClass.this.x).+(other.x)
}
}
Run Code Online (Sandbox Code Playgroud)