2017-07-22 74 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