我已经用泛型定义了一个函数,但我在理解编译器给我的错误时遇到了一些麻烦。问题可以简单地表达为:
def myfunc[T <: MyClass](param:MyClass):T = param
它param
在我的正文中给了我这个错误:MyClass 类型的表达式不符合预期的 T 类型。
为什么?param
符合 T 的上限。如何在不将 param 转换为 T 的情况下进行类似的工作?
好的。假设,您有以下内容:
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
正确。希望它澄清Dog
Animal
你有向后的差异。如果T <: MyClass
,那么您可以提供预期的T
位置。MyClass
但是你不能给出预期的MyClass
地方。T
为了显示:
def myfunc(x: Any): String = x
出于同样的原因,这给出了同样的错误。AnAny
不是String
, 你MyClass
的也不是T
。
这可能是您的意思:
def myfunc[T >: MyClass](param:MyClass):T = param
哪个工作正常。
您认为param与T相关的假设是因为它们具有共同的祖先是错误的。
例如,基类A可以有两个子类B和C。如果T属于B类型并且param属于C类型,则param不是与T相关的类型。
看这个:
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 等)并查看编译器所说的内容很有用。
我希望能帮助你。
参数类型是 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”