2016-07-03 83 views
0

說我做一個參數泛型方法:在什麼情況下不正確階String轉換爲java.lang.String

trait MyTrait[T] { 
    def method():T 
} 

,然後擴展它和參數多態。這:

class MyClass extends MyTrait[java.lang.String] { 
    def method() = "foo" 
} 

是一樣的:

class MyClass extends MyTrait[String] { 
    def method() = "foo" 
} 

但是,當你犯了一個特質方法parametrizes像這樣一個lambda:

trait MyTrait { 
    def apply[T](input:()=>T):T 
} 

那麼你有沒有真幸運。這:

class MyClass extends MyTrait { 
    def apply(input:()=>java.lang.String) = "foo" 
} 

會導致這樣的:

Error:(25, 45) type mismatch; 
found : java.lang.String("foo") 
required: String 
     def apply[String](input:()=>String) = "foo" 
            ^

然而,這是好的:

class MyClass extends MyTrait { 
    def apply[String](input:()=>String) = new String("foo") 
} 

那麼在什麼情況下不scalac實際上知道轉換需要做的事情,並在它不是什麼情況?

而且,即使我寫出來的整個路徑java.lang.String中類型

class MyClass extends MyTrait { 
    def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo") 
} 

它拋出另一個錯誤:

Error:(25, 21) ']' expected but '.' found. 
     def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo") 
        ^

如果我要真正做到這一點後者通過直接模板化java.lang.String的方式,我將如何去做呢?

+1

'def apply [String]'您在這裏聲明一個名爲'String'的類型參數。 –

回答

3

class MyClass extends MyTrait { 
    def apply[String](input:()=>String) = new String("foo") 
} 

不精。結果爲class type required but String found。這裏的問題是當你用參數化方法擴展一個類時,你不會聲明一個類型參數。您在使用該方法時聲明它。

讓我們重寫:

class MyClass extends MyTrait { 
    def apply[String](input:()=>String) = input() 
} 

現在觀察:

scala> (new MyClass).apply[String](() => "foo") 
res0: String = foo 

scala> (new MyClass).apply[Int](() => 5) 
res1: Int = 5 

它的工作原理,因爲當你宣稱這一點:

def apply[String](input:()=>String) = input() 

String參數的名稱。如果你寫了T,XyzzyManISuckAtTypeParameters而不是String以上,它將是完全相同的東西。你在說你會得到一個類型參數,你將會得到的名字,這個類型參數String,這就是返回函數的值,並且通過替代,方法的apply

當我打電話apply[Int](() => 5),斯卡拉將的定義與Int取代String

+0

哎呀,這真是我的愚蠢。謝謝你的回覆。 – ChoppyTheLumberjack

相關問題