【问题标题】:Scala: Constructor taking either Seq or varargsScala:构造函数采用 Seq 或 varargs
【发布时间】:2011-10-25 19:19:16
【问题描述】:

我猜测,出于兼容性原因,可变参数Any* 的类型是 Array[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: 第 13 行的 Seq[(String, String)])Api 在擦除后具有相同的类型: (api_url: java.lang.String, params: Seq)Api

那么如何定义一个使用可变参数或序列的构造函数?

【问题讨论】:

    标签: scala types constructor variadic-functions


    【解决方案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())
    }
    

    【讨论】:

    • 就我而言,这是最好的解决方案。它允许您在不牺牲:_* 的可读性的情况下执行Api("url")Api("url", "a" -> "b")Api("url", Seq("a" -> "b"))
    【解决方案2】:

    采用可变参数的方法也总是采用序列,因此无需定义辅助构造函数或重载方法。

    给定

    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,所以无论如何这都是无操作的。

    【讨论】:

    【解决方案3】:

    不:实际上,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)
    }
    

    【讨论】:

    • ……这不是……真的很恶心吗?
    • 好吧,随意提供一个不那么“恶心”的解决方案!
    • 当我想出一个时,我会的。现在,我将只讨论varargs 构造函数。 ^^
    • 为什么不保留可变参数构造函数,让调用者做seq:_* 的事情,如果他愿意?
    • 设计新界面应该更喜欢vargargs而不是Seq
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2011-02-11
    • 2013-06-14
    • 2012-01-09
    • 2011-04-21
    相关资源
    最近更新 更多