#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
ofpublic interface TBase<T extends TBase, F> {}
иscalac
ofobject 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
}
компилируется без ошибок.