Как выразить границы типов для универсального интерфейса со стертым типом в Scala?

#scala #generics #type-bounds

#scala #общие #границы типов

Вопрос:

Вот интерфейс, определенный в 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
  

Комментарии:

1. Не воспроизводится сразу. javac of public interface TBase<T extends TBase, F> {} и scalac of object Foo { def test[TB[A <: TBase[_, _], B] <: TBase[A, B]](x: TB[_, _]) = x } , похоже, компилируются без ошибок. Откуда именно берется ошибка? Кроме того, это здесь имеет <?, ?> .

2. @AndreyTyukin Вероятно, это зависит от версии libthrift . Ваша ссылка на 0.9. В 0.12 это public interface TBase<T extends TBase<T,F>, F extends TFieldIdEnum> extends Comparable<T>, TSerializable, Serializable .

3. @w0mTea Какие у вас версии libthrift и Scala?

4. @DmytroMitin Я использую Scala 2.11.8 и очень старую версию apache thrift, thrift-0.5.0

5. @w0mTea я обновил свой ответ. С этими версиями я не могу воспроизвести вашу ошибку. Попробуйте sbt clean compile . A <: TBase[A, B], B <: TFieldIdEnum Работает ли для вас?

Ответ №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
}
  

компилируется без ошибок.