参数类型+函数需要一个字符串作为第二个参数?

时间:2010-06-27 16:13:10

标签: scala types type-mismatch type-parameter

  

class TestClass[T](val x: T) { def +(other: TestClass[T]) = x + other.x }

这个定义给了我以下编译错误:

错误:类型不匹配;
发现:T
必需:字符串
def +(其他:TestClass [T])= x + other.x

是不可能使用Int或Double作为类型参数并在Scala中使用添加??

1 个答案:

答案 0 :(得分:9)

首先,错误消息具有误导性。 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

在C ++中,类型检查在每个调用站点提供type参数后完成。所以这种代码风格可行。在Scala中,泛型方法必须在其定义时进行类型检查,仅基于抽象类型的边界。

根据VonC的建议,您可能希望在类型参数T上提供上下文绑定,以约束if是否具有Numeric特征的相应实例的类型。

class TestClass[T: Numeric](val x: T) { 
  def +(other: TestClass[T]): T = {
    val num = implicitly[Numeric[T]]
    import num._
    x + other.x
  }
}

以下是显示所有隐含的内容:

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)
  }
}