scala泛型和继承
发布时间:2020-12-16 19:05:21 所属栏目:安全 来源:网络整理
导读:我在 scala中有以下层次结构的问题: class ScalaGenericTest { def getValue[A,B : Abstract[A]](clazz: B): A = clazz.a def call: String = { val sub: Subclass = new Subclass getValue(sub) }}class Subclass extends Abstract[String] { def a: Strin
我在
scala中有以下层次结构的问题:
class ScalaGenericTest { def getValue[A,B <: Abstract[A]](clazz: B): A = clazz.a def call: String = { val sub: Subclass = new Subclass getValue(sub) } } class Subclass extends Abstract[String] { def a: String = "STRING" } abstract class Abstract[A] { def a: A } 编译器似乎无法在调用getValue函数时绑定泛型参数A – 我认为应该能够从Subclass的定义推断出这一点.编译错误如下:
如果我明确地将通用类型的参数传递给方法,即getValue [String,Subclass](sub),那么编译器应该能够推断出来吗? 相同的层次结构在Java中运行正常: public class JavaGenericTest { public <T,U extends Abstract<T>> T getValue(U subclass) { return subclass.getT(); } public String call(){ Subclass sub = new Subclass(); return getValue(sub); } private static class Subclass extends Abstract<String> { String getT(){ return "STRING"; } } private static abstract class Abstract<T> { abstract T getT(); } } 我对Scala很新,所以可能有一些我错过的微妙之处. 提前感谢任何帮助! 解决方法
这是Scala类型推断的一个限制.这个问题在
SI-2272中描述(该示例使用了含义,但是明确使用时会出现相同的错误).它已经关闭,不会修复.
在这个问题上,Adriaan Moors建议避免双方都有类型变量的约束.即. B<:摘要[A].一个简单的解决办法是完全避免第二个类型的参数. def getValue[A](clazz: Abstract[A]): A = clazz.a scala> val sub = new Subclass sub: Subclass = Subclass@585cbda6 scala> getValue(sub) res11: String = STRING 另外,Adriaan还提供了一种使用隐含的<:<作为另一个工作.把它放在你的例子的上下文中,它看起来像: def getValue[A,B](b: B)(implicit ev: B <:< Abstract[A]): B = b.a 其中<:<是通过Predef隐含提供的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |