2014-12-21 44 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(參數類型名稱)不相同。我不知道是否可以實現參數化定義之外的特定類型的加號功能。如果參數適用於所有類,則使用類類型參數;如果參數僅適用於該方法,則使用方法參數。這只是方法的可見性和責任問題。在方法

相關問題