我已经使用泛型定义了一个函数,我在理解编译器给出的错误时遇到了一些麻烦。问题可以简单地表达为:
def myfunc[T <: MyClass](param:MyClass):T = param
它在我身体的param
上给出了这个错误:MyClass类型的表达式不符合预期的类型T.
为什么呢? param
符合T的上限。如果不依靠将参数转换为T,我怎么能做出像这样的工作呢?
答案 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
这是正确的,因为Dog
是Animal
。希望它澄清
答案 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”