2014-12-21 41 views
3

想不通有什么错此代码:scala 2.10:为什么会出现类型不匹配?

trait NumberLike 
    { 
    def plus[T](a: T, b: T): T 
    } 

    class IntegerNumberLike extends NumberLike 
    { 
    def plus[Int](a: Int, b: Int): Int = 2 // type mismatch; found : scala.Int(2) required: Int 
    } 

但如果我这样做,这样一来,它的工作原理:

trait NumberLike[T] 
    { 
    def plus(a: T, b: T): T 
    } 

    class IntegerNumberLike extends NumberLike[Int] 
    { 
    def plus(a: Int, b: Int): Int = 2 
    } 

所以,我有两个问题:

  • 为什么第一个代码示例不起作用?
  • 一般来说,何时应该使用类类型参数,何时应该使用方法类型参数?

回答

2

类型参数很像其它参数,实际参数的名称不显著:plus[Int](a: Int, b: Int): Int完全相同plus[T](a: T, b: T): T

现在,很容易理解为什么plus[T](a: T, b: T): T = 2不能编译,不是吗?因为2不是T类型。

至于你的第二个问题,很难准确回答,因为它很宽泛。简而言之,参数化类和方法分别定义了类或方法的模板。把它看作是类/方法的一个而不是单个对象。例如,而不是plus[T] (a: T, b: T): T,一个可以写:

def plus(a: Int, b: Int): Int 
def plus(a: Long, b: Long): Long 
def plus(a: Double, b: Double): Double 

或者,而不是class NumberLike[T],你可以有:

class IntLike 
class LongLike 
class DoubleLike 

看着这样,你可以问自己一个问题,你在设计什么:它是一个班级家族还是一个方法家族?回答这个问题会告诉你,你是否应该参数化一个类,一个方法,或者两者都可以......考虑:

class Iterable[+A] { 
    ... 
    def def reduceLeft[B >: A](op: (B, A) ⇒ B): B 
    ... 
} 
1

定义:

def plus[Int](a: Int, b: Int): Int 

相当于

def plus[T](a: T, b: T): T 

例如,你可以更清楚地看到它通过下面的例子:

type Int = String 

    def main(args: Array[String]) { 
    val x: Int = "foo" 
    println(x) 
    } 

你在哪里得到没有错误和“foo”打印。由于您只是将参数类型重命名为Int(而不是T)。这就是为什么编译器会抱怨Int(在这种情况下值为2)和Int(参数类型名称)不相同。我不知道是否可以实现参数化定义之外的特定类型的加号功能。如果参数适用于所有类,则使用类类型参数;如果参数仅适用于该方法,则使用方法参数。这只是方法的可见性和责任问题。在方法

相关问题