我猜测,出于兼容性原因,vararg参数Any*
的类型是数组[任意] - 如果我错了,请更正此问题。但是,这并不能解释以下错误:
class Api(api_url: String, params: Seq[(String, String)]) {
def this(api_url: String, params: (String, String)*)
= this(api_url, params.seq)
}
此代码无法编译,但会发出警告:
双重定义: 构造函数Api:(api_url:String,params:(String,String)*)Api和构造函数Api:(api_url:String,params: Seq [(String,String)])第13行的Api在擦除后具有相同的类型: (api_url:java.lang.String,params:Seq)Api
那么如何定义采用varargs或序列的构造函数?
答案 0 :(得分:31)
采用varargs的方法也总是采用序列,因此不需要定义辅助构造函数或重载方法。
鉴于
class Api(api_url: String, params: (String, String)*)
你可以这样称呼它
new Api("url", ("a", "b"), ("c", "d"))
或
val seq = Seq(("a", "b"), ("c", "d"))
new Api("url", seq:_*)
另外,在你的问题中,你在params参数上调用方法seq。这可能不符合您的意图。 seq用于确保对结果集合的操作按顺序而不是并行执行。该方法是在Scala版本2.9.0中的并行集合中引入的。
你可能想要使用的是toSeq,它返回它在转换为Seq时使用的集合(或者如果它已经是Seq则返回它自己)。但是由于varargs参数已经被输入为Seq,所以无论如何都是无操作。
答案 1 :(得分:9)
否:实际上,Any*
实际上几乎与Seq[Any]
相同,而不是Array[Any]
。
要消除两者之间的歧义,您可以使用该技术添加虚拟隐式参数以使签名不同:
class Api(api_url: String, params: Seq[(String, String)]) {
def this(api_url: String, params: (String, String)*)(implicit d: DummyImplicit) =
this(api_url, params)
}
答案 2 :(得分:1)
我认为您希望方法调用更漂亮,因此使用_*
进行显式调用不是一种选择。在这种情况下,您可以通过方法重载来解决问题。
class Api(api_url: String, params: Seq[(String, String)]) {
def this(api_url: String, param : (String, String), params: (String, String)*)
= this(api_url, param +: params)
def this(api_url: String)
= this(api_url, Seq())
}