2010-06-27 93 views
2

class TestClass[T](val x: T) { def +(other: TestClass[T]) = x + other.x }参数类型+函数需要一个字符串作为第二个参数?

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

错误:类型不匹配;
发现:T
需要:字符串
DEF +(其它:识别TestClass [T])= X + other.x

是它不可能使用int或double作为类型参数,并使用另外Scala中??

+1

见http://stackoverflow.com/questions/2096414/addition-with-generic-type-parameter-in-scala和http://stackoverflow.com/questions/1252915/scala-how-to-define-generic-function-parameters初学者:你可能需要一个隐式的''数字''类型'T'在这里。 – VonC 2010-06-27 16:15:34

回答

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++中,提供了类型参数后的类型检查完成后,在每个调用站点。所以这种风格的代码将起作用。在Scala中,泛型方法必须根据其定义进行类型检查,仅基于抽象类型的边界。

正如VonC所建议的那样,您可能希望提供一个上下文绑定在类型参数T上,以约束是否具有对应于Numeric特征的实例的类型。

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

以下是这看起来与所有的implicits作出了明确:

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) 
    } 
} 
相关问题