在Scala中创建元组时键入绑定错误

dar*_*kjh 5 scala existential-type

说我有一个类型

trait Mode[T]
trait MyType[T, M <: Mode[T]]
Run Code Online (Sandbox Code Playgroud)

这编译

val t: MyType[_, _] = ???
t
Run Code Online (Sandbox Code Playgroud)

但不是这个

val t: MyType[_, _] = ???
"some_string" -> t
Run Code Online (Sandbox Code Playgroud)

错误说的是 type arguments [_$0,_$1] do not conform to trait MyType's type parameter bounds

所以我的问题是为什么这不会在元组创建时编译?

Leo*_*o C 2

实际上, 和t都会"some string" -> t在运行时因同样的问题而中断:

import scala.language.existentials
import scala.reflect.runtime.universe._

type SubMode[T] = M forSome { type M <: Mode[T] }

val t: MyType[_, _] = new MyType[String, SubMode[String]] {}
// t: MyType[_, _] = $anon$1@596afb2f

"some string" -> t
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]

reify(t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]

reify("some string" -> t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
Run Code Online (Sandbox Code Playgroud)

事实上,编译时的问题并不是元组特有的。例如:

List(t)
// error: type arguments [_$1,_$2] do not conform to trait MyType's type parameter bounds [T,M <: Mode[T]]
Run Code Online (Sandbox Code Playgroud)

我的猜测是,虽然单独的定义t不会触发编译错误,但额外的“触摸”t可能会触发。如果你让编译器推断正确的类型,一切都会正常工作:

val t2 = new MyType[String, SubMode[String]] {}
t2: MyType[String,SubMode[String]] = $anon$1@19d53ab4

"some string" -> t2
// res1: (String, MyType[String,SubMode[String]]) = (some string,$anon$1@19d53ab4)

List(t2)
// res2: List[MyType[String,SubMode[String]]] = List($anon$1@19d53ab4)
Run Code Online (Sandbox Code Playgroud)