首页 文章

Scala:构造函数采用Seq或varargs

提问于
浏览
19

我猜测,出于兼容性原因,vararg参数类型 Any* 是数组[任意] - 如果我错了,请更正此问题 . 但是,这并不能解释以下错误:

class Api(api_url: String, params: Seq[(String, String)]) {
  def this(api_url: String, params: (String, String)*)
    = this(api_url, params.seq)
}

此代码无法编译,但会发出警告:

double definition:构造函数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或序列的构造函数呢?

3 回答

  • 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())
    }
    
  • 29

    采用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,所以无论如何都是无操作 .

  • 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)
    }
    

相关问题