【问题标题】:How to express type bounds on a type erased generic interface in Scala?如何在 Scala 中表示类型擦除泛型接口的类型边界?
【发布时间】:2019-09-05 02:19:02
【问题描述】:

这是一个用Java定义的接口:

public interface TBase<T extends TBase, F extends TFieldIdEnum>

当我尝试为使用此接口的方法添加类型边界时,如下所示:

def test[TB[A <: TBase[_, _], B <: TFieldIdEnum] <: TBase[A, B]](x: TB[_, _]) = x

发生错误:

type T's bounds <: TBase are stricter than type A's declared bounds <: TBase[_, _]

那么我该如何表达类型界限

T <: TBase

在 Scala 中?


附加信息:

我使用的是 Scala 2.11.8,界面来自非常旧的 apache thrift 版本,thrift-0.5.0

经过多次尝试, 到现在为止唯一成功的就是去掉了更高种类的类型参数:

def test[A <: TBase[_, _], B <: TFieldIdEnum](x: TBase[A, B]) = x

【问题讨论】:

  • 无法立即重现。 public interface TBase&lt;T extends TBase, F&gt; {} 的 javac 和 object Foo { def test[TB[A &lt;: TBase[_, _], B] &lt;: TBase[A, B]](x: TB[_, _]) = x } 的 scalac 似乎编译没有错误。错误究竟来自哪里?此外,this here 有 &lt;?, ?&gt;。
  • @AndreyTyukin 这可能取决于libthrift 的版本。您的链接是 0.9。在 0.12 中是 public interface TBase&lt;T extends TBase&lt;T,F&gt;, F extends TFieldIdEnum&gt; extends Comparable&lt;T&gt;, TSerializable, Serializable。
  • @w0mTea 您的libthrift 和Scala 版本是什么?
  • @DmytroMitin 我使用的是 Scala 2.11.8 和一个非常旧的 apache thrift 版本,thrift-0.5.0
  • @w0mTea 我更新了我的答案。使用这些版本,我无法重现您的错误。试试sbt clean compile。 A &lt;: TBase[A, B], B &lt;: TFieldIdEnum 适合你吗?

标签: scala generics type-bounds


【解决方案1】:

与

scalaVersion := "2.12.8"
libraryDependencies += "org.apache.thrift" % "libthrift" % "0.12.0"

代码

import org.apache.thrift.{TBase, TFieldIdEnum}
import scala.language.higherKinds

object App {
  def test[TB[A <: TBase[_, _], B <: TFieldIdEnum] <: TBase[A, B]](x: TB[_, _]) = x
}

产生错误

Error:(5, 55) type arguments [A,B] do not conform to trait TBase's type parameter bounds [T <: org.apache.thrift.TBase[T,F],F <: org.apache.thrift.TFieldIdEnum]
  def test[TB[A <: TBase[_, _], B <: TFieldIdEnum] <: TBase[A, B]](x: TB[_, _]) = x

这不完全是你的,但很相似。

最简单的解决方法是

  def test[TB[A <: TBase[A, B], B <: TFieldIdEnum] <: TBase[A, B]](x: TB[_, _]) = x

有

scalaVersion := "2.11.8"
resolvers += "twitter-repo" at "http://maven.twttr.com"
libraryDependencies += "org.apache.thrift" % "libthrift" % "0.5.0"

我无法重现您的错误。

import org.apache.thrift.{TBase, TFieldIdEnum}
import scala.language.higherKinds

object App {
  def test[TB[A <: TBase[_, _], B <: TFieldIdEnum] <: TBase[A, B]](x: TB[_, _]) = x
}

编译没有错误。

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多