(T,T)*
在擦除后解析为Seq[(T,T)]
,但是如何将(T,T)*
本身表示为一种类型呢?
问的原因是我正在使用一个 API 来定义:
def foo(bar: (String,String)*) = ...
但是当我尝试通过Seq[(String,String)]
时失败了.
我的拉取请求添加:
def foo(bar: Seq[(String,String)]) = ...
由于擦除后2种方法具有相同的类型而爆炸。
星形投影是否可以表示为具体类型?
如果您按照这样的:_*
来传递Seq
:
val s:Seq[(String, String)] = Seq( ("a", "b"), ("c", "d"), ... )
foo(s:_*)
因此,您不应该同时需要两个签名。
要消除已删除签名的歧义:
scala> class X { def f(is: Int*) = is.sum }
defined class X
scala> class Y extends X { def f(is: Seq[Int])(implicit d: DummyImplicit): Int = f(is: _*) }
defined class Y
scala> new Y().f(1 to 10)
res3: Int = 55
或者这样更好,集合中的签名总是看起来像这样,表示"两个或更多":
scala> class X {
| def f(i: Int): Int = i
| def f(is: Seq[Int]): Int = is.sum
| def f(i: Int, j: Int, rest: Int *): Int = i + j + rest.sum
| }
defined class X
scala> new X().f(3)
res9: Int = 3
scala> new X().f(3,4)
res10: Int = 7
scala> new X().f(3,4,5)
res11: Int = 12
scala> new X().f(1 to 10)
res12: Int = 55
不能引用重复的参数类型,就像不能引用按名称的参数类型一样。 所以你不能转换成它。 但是,您可以按名称反射性地检测它:
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> typeOf[X].member(TermName("f")).asMethod.paramss.flatten.head.asTerm.typeSignature.typeSymbol.name
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
res4: reflect.runtime.universe.Symbol#NameType = <repeated>
有内部 API,definitions.isRepeated(sym)
,如果你想为它投射的话。