加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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的定义推断出这一点.编译错误如下:

inferred type arguments [Nothing,Subclass] do not conform to method getValue’s type parameter bounds [A,B <: Abstract[A]]

如果我明确地将通用类型的参数传递给方法,即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隐含提供的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读