代码之家  ›  专栏  ›  技术社区  ›  Alex

在Scala中扩展泛型特征的返回类

  •  1
  • Alex  · 技术社区  · 8 年前

    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()
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   Alexey Romanov    8 年前

    你真正想要的是每个人 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()
      }
    }
    
        2
  •  1
  •   jwvh    8 年前

    getConverter[N] 应该返回某种类型的 Converter[Integer,N] 但是 StringDuplicatorConverter Converter[Integer,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