【问题标题】:Why is it impossible to specify the default value of a Scala varargs parameter?为什么不能指定 Scala 可变参数的默认值?
【发布时间】:2013-08-20 21:09:26
【问题描述】:

我写了一个类,它接受一个可变参数作为参数,并指定它的默认值,这样用户就可以在不指定参数的情况下经常实例化它:

class MyClass(values: Int* = 42) { }

但是,编译器和 REPL 给我以下错误:

<console>:7: error: type mismatch;
 found   : Int(42)
 required: Int*
       class MyClass(values: Int* = 42) { }
                                ^
<console>:7: error: a parameter section with a `*'-parameter is not allowed to have default arguments
       class MyClass(values: Int* = 42) { }

作为一种解决方法,我尝试了以下方法,但它也不起作用:(显然它非常模棱两可。)

class MyClass(value: Int = 42, otherValues: Int*) { }

我想知道为什么不允许使用 varargs 参数的默认值。这里的推理或技术原因是什么? (我的猜测是指定一个空的可变参数需要一些特殊的语法或习惯用法,但我不确定这是否足够。)

【问题讨论】:

    标签: scala variadic-functions default-parameters


    【解决方案1】:

    稍微考虑一下,我认为这只是不增加太多复杂性的问题,假设你有

    def f(a: A, xs: X* = Seq(x0, x1)) = ???
    

    现在调用者这样使用:f(a)

    我们如何知道调用者是打算传递一个零长度的X* 列表,还是想通过不提供X* 来触发默认参数?在您的示例中,您假设第二种选择是唯一的情况,并且编译器需要提供默认参数值。但是空的Seq() 已经是调用者提供的完全有效的值。我猜来电者可以写f(a, Seq(): _*),但这很麻烦。

    【讨论】:

    • 那为什么def foo(result: Int = 0, xs: String*) = ??? 不被接受呢?编译器将foo(0, "impossible to compile") 识别为合法结构是完全可行的。
    • @om-nom-nom,不确定我是否关注你。我正在回答为什么我们可能不想支持def foo(result: Int = 0, xs: String* = Seq("some", "default")) = ???
    • 是的,但是编译器在我的例子中设置了相同的限制(至少给了我们相同的编译错误),所以我想可能还有其他一些原因可以统一这两种情况
    【解决方案2】:

    来自 Scala 规范(第 4.6.2 节)

    不允许在参数中定义任何默认参数 有重复参数的部分

    也许解决方法会有所帮助?

    class MyClass(values: Int*) {
      def this() = this(5)
    }
    

    【讨论】:

    • 它没有解释为什么会这样,只是假设这种否认。
    【解决方案3】:

    不仅在 Scala 中,Varargs 是对参数列表的抽象,如果我没记错的话,它被简化为 Seq,一个参数列表。由此得出,您对values: Int* = 42 的期望是什么?那么,当你调用这个方法时,应该如何将参数传递给这个方法呢?

    【讨论】:

    • 但你至少可以做到values: Int* = (Array(42): Int* )
    【解决方案4】:

    另一种解决方法是明确 Seq:

    class MyClass(values: Seq[Int] = Seq(42)) { }
    

    【讨论】:

      【解决方案5】:

      可变参数的默认值没有意义,因为您无法确定应该传递多少个参数。这不是scala的限制,这是逻辑限制。

      【讨论】:

        猜你喜欢
        • 2012-10-01
        • 2020-03-30
        • 2014-07-18
        • 1970-01-01
        • 2013-05-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多