在另一个问题中,我建议with在通常使用<:或使用的地方使用<:<.因此,不是以下列两种方式之一定义函数:
scala> def f[A,C <: Seq[A]](xs: C) = 0
f: [A, C <: scala.collection.immutable.Seq[A]](xs: C)Int
scala> f(List(1))
<console>:54: error: inferred type arguments [Nothing,List[Int]] do not conform to method f's type parameter bounds [A,C <: scala.collection.immutable.Seq[A]]
f(List(1))
^
scala> implicit def f[A,C](xs: C)(implicit ev: C <:< Seq[A]) = new { def foo = 0 }
f: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Seq[A]])java.lang.Object{def foo: Int}
scala> List(0) foo
<console>:54: error: Cannot prove that List[Int] <:< scala.collection.immutable.Seq[A].
List(0) foo
^
scala> f(List(0)) foo
res17: Int = 0
Run Code Online (Sandbox Code Playgroud)
人们可以这样做:
scala> implicit def f[A,C](xs: C with Seq[A]) = new { def foo = 0 }
f: [A, C](xs: C with scala.collection.immutable.Seq[A])java.lang.Object{def foo: Int}
scala> List(0) foo
res18: Int = 0
Run Code Online (Sandbox Code Playgroud)
我的问题是:除了上述的特定情况下,一个时,应使用with,而不是<:或<:<对类型参数?为什么不总是使用with?我正在寻找关于替代方案中细微差别的讨论.谢谢.
意义完全不同.如你所知,这C <: Seq[A]意味着它C是一个子类型Seq[A]; xs: C with Seq[A]没有任何限制C,但意味着xs应该是a C和a Seq[A].因此,您通常应该使用您实际意味着的那个.
在def f[A,C <: Seq[A]](xs: C)问题是,Scala的编译器无法推断A,因为它没有在参数的类型明确出现.我认为原则上没有任何理由无法推断A; 它目前没有.与更换型C with Seq[A]装置A现在出现在的类型xs和允许编译器推断A.所以,如果你真的是指束缚,但A要推断,你实际上需要写
implicit def f[A,C <: Seq[A]](xs: C with Seq[A])
Run Code Online (Sandbox Code Playgroud)
而不是你的第三个定义,这就是链接问题的答案.