返回泛型类型时出错

时间:2018-08-01 23:00:28

标签: scala generics

我有一个采用通用类型并返回该类型的抽象类:

abstract class Foo {
  def apply[T]:T
}

class FooImpl extends Foo { 
  def apply[Int]: Int = 1 
}

但是错误:

 error: type mismatch;
 found   : Int(1)
 required: Int
       class FooImpl { def apply[Int]: Int = 1 }

为什么会发生?我该如何解决?

2 个答案:

答案 0 :(得分:3)

您要声明一个名为Int的类型参数,然后将其用作返回类型。因此它不同于scala.Int

我认为这种情况下的解决方案是将类型参数T移至类而不是方法:

abstract class Foo[T] {
  def apply: T
}

class FooImpl extends Foo[Int] { 
  def apply: Int = 1 
}

答案 1 :(得分:1)

Bubletan已经解释了为什么它不能与用作类型参数名称的Int一起使用。

如果您不想向Foo添加任何类型参数,则可以做几件事。

  1. 使用类型成员:

    abstract class Foo {
      type T
      def apply: T
    }
    
    class FooImpl extends Foo { 
      type T = Int
      def apply: T = 1 
    }
    

    这使您可以在多种方法中使用公用类型T

  2. 您可以只在界面中使用Any,然后在实现中指定更精确的类型:

    abstract class Foo {
      def apply: Any
    }
    
    class FooImpl extends Foo { 
      def apply: Int = 1 
    }
    
    val x: Int = (new FooImpl).apply
    

    在这里,当编译器看到Int上调用的方法apply时,编译器将能够正确推断出更具体的类型FooImpl

  3. 是否可以保留T作为参数?然后,您必须在方法apply中添加至少某种隐式参数,以使您可以生成T

    trait CanCreate[T] {
      def create: T
    }
    
    trait Foo {
      def apply[T](implicit c: CanCreate[T]): T = c.create
    }
    

    没有其他使您能够生成T实际实例的参数,您所能做的就是抛出异常(从而“返回Nothing”)。