Scala:将具体类型与带有边界的泛型相符

时间:2012-12-13 01:02:35

标签: scala generics

我已经使用泛型定义了一个函数,我在理解编译器给出的错误时遇到了一些麻烦。问题可以简单地表达为:

def myfunc[T <: MyClass](param:MyClass):T = param

它在我身体的param上给出了这个错误:MyClass类型的表达式不符合预期的类型T.

为什么呢? param符合T的上限。如果不依靠将参数转换为T,我怎么能做出像这样的工作呢?

5 个答案:

答案 0 :(得分:7)

确定。假设您有以下内容:

class Animal
class Dog extends Animal

现在让我们的功能如下:

def myfunc[T <: Animal](param:Animal):T = param

现在假设,编译器不会抛出错误。在调用myfunc[Dog](new Animal)时,它应根据函数定义返回Dog。但实际上,你只是发回Animal。哪个不应该被允许。因此错误。

现在有了:

def myfunc[T >: Dog](param:Dog):T = param

在此致电myfunc[Animal](new Dog)。返回类型为Animal。但该函数返回Dog这是正确的,因为DogAnimal。希望它澄清

答案 1 :(得分:4)

你有向后的差异。如果T <: MyClass,那么您可以提供T,其中MyClass是预期的。但是,您无法提供MyClass预期T的位置。

举例说明:

def myfunc(x: Any): String = x

出于同样的原因,这会产生同样的错误。 Any不是String,而您的MyClass不是T

这就是你的意思:

def myfunc[T >: MyClass](param:MyClass):T = param

哪种方法正常。

答案 2 :(得分:1)

看看这个:

class A(); class B extends A;

scala> def myfunc[T <: A,U >: A](param: U):T = param
<console>:8: error: type mismatch;
found   : param.type (with underlying type U)
required: T
       def myfunc[T <: A,U >: A](param: U):T = param

你的param:MyClass确实有一个下限(>: MyClass),就像在Java中一样 - 它可以是MyClass的任何后代。那么,如何运行myfunc(B)并返回类图上比A更高的类型?在继承图中B被认为低于A,你返回B但是它确实是<: A。错误。

有时显式声明所有类型,如T,U,V等,看看编译器说的是什么。

答案 3 :(得分:1)

您认为 param T 有关,因为它们共享一个共同的祖先是错误的。

例如,基类 A 可以有两个子类 B C 。如果 T 的类型为 B param 的类型为 C ,则 param 为不属于与 T 相关的类型。

答案 4 :(得分:0)

我希望能帮助你。

参数类型是T而不是MyClass。

object StackOverFlow13851352 extends App {
    class MyClass
    class YourClass extends MyClass
    def myfunc[T <: MyClass](param: T): T = param

    val clazz: YourClass = myfunc(new YourClass)
}

Scala code runner版本2.10.0-RC2 - 版权所有2002-2012,LAMP / EPFL

java版“1.7.0_09”