3

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

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

param在我的正文中给了我这个错误:MyClass 类型的表达式不符合预期的 T 类型。

为什么?param符合 T 的上限。如何在不将 param 转换为 T 的情况下进行类似的工作?

4

5 回答 5

8

好的。假设,您有以下内容:

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. 但是该函数返回的 a 和 a一样Dog正确。希望它澄清DogAnimal

于 2012-12-13T05:36:25.200 回答
4

你有向后的差异。如果T <: MyClass,那么您可以提供预期的T位置。MyClass但是你不能给出预期的MyClass地方。T

为了显示:

def myfunc(x: Any): String = x

出于同样的原因,这给出了同样的错误。AnAny不是String, 你MyClass的也不是T

这可能是您的意思:

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

哪个工作正常。

于 2012-12-13T01:23:32.953 回答
1

您认为paramT相关的假设是因为它们具有共同的祖先是错误的。

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

于 2012-12-13T19:05:25.923 回答
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 等)并查看编译器所说的内容很有用。

于 2012-12-13T01:22:39.650 回答
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 代码运行器版本 2.10.0-RC2 -- 版权所有 2002-2012,LAMP/EPFL

java版本“1.7.0_09”

于 2012-12-13T01:12:48.360 回答