2017-07-22 106 views
1

Scala代碼:收益類斯卡拉擴展通用特質

trait Converter[S, T] { 
    def convert(source: S): T 
} 

class StringDuplicatorConverter extends Converter[Integer, String] { 
    override def convert(source: Integer): String = { 
    source.toString + source.toString 
    } 
} 

// whatever, the point is to show potentially many 'converters' 
// from Integer (for example) to something 
class SomeOtherConverter extends Converter[Integer, User] { 
    override def convert(source: Integer): User = { 
    User(source) 
    } 
} 

trait ConverterProvider { 
    def getConverter[N]: Converter[Integer, N] 
} 

class MyClass extends ConverterProvider { 
    override def getConverter[N]: Converter[Integer, N] = { 
    new StringDuplicatorConverter() 
    } 
} 

Error:(17, 5) type mismatch; 
found : StringDuplicatorConverter 
required: Converter[Integer,N] 
    new StringDuplicatorConverter() 

回答

1

可能是你真正想要的是每個ConverterProvider提供轉換到一個特定的類型(否則MyClass的定義並沒有太大的意義:它應該針對不同N返回不同的轉換器,並不總是StringDuplicatorConverter)。如果是這樣,正確的定義是

trait ConverterProvider[N] { 
    def getConverter: Converter[Integer, N] 
} 

class MyClass extends ConverterProvider[String] { 
    override def getConverter: Converter[Integer, String] = { 
    new StringDuplicatorConverter() 
    } 
} 
1

是。撥打getConverter[N]的電話應返回Converter[Integer,N]類型的內容,但StringDuplicatorConverter的類型爲Converter[Integer,String]。由於N不限於String,因此它們是不同的類型,所以不會編譯。

如果編譯器得到了一些保證N是一個或超級類型String那麼它會工作。這可以通過返回式協做...

trait Converter[S, +T] { ... 

...然後定義getConverter和覆蓋,就像這樣:

def getConverter[N >: String]: Converter[Integer, N] 

現在編譯並似乎工作。

val mc = new MyClass 
mc.getConverter.convert(7) // res0: String = 77