【问题标题】:Why are default arguments not allowed in a Scala section with repeated parameters?为什么在具有重复参数的 Scala 部分中不允许使用默认参数?
【发布时间】:2015-11-20 01:12:02
【问题描述】:

根据 Scala 规范 Section 4.6.3:

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

其实如果我定义如下case类:

case class Example(value: Option[String] = None, otherValues: String*)

我得到的结果是符合规范的预期结果:

error: a parameter section with a `*'-parameter is not allowed to have default arguments
   case class Example(value: Option[String] = None, otherValues: String*)

但问题是为什么不允许这样做?类的第一个参数完全独立于重复参数,那么为什么会有这个限制呢?

【问题讨论】:

    标签: scala


    【解决方案1】:

    因为你可以这样做:

    case class Example(value: String = "default", otherValues: String*)
    

    现在如果你调用Example("Hello", "world"),第一个"Hello"是属于value还是属于otherValues

    您可能会争辩说您的示例中的类型不同,但规则变得过于复杂而无法遵循。例如经常与Any 类型一起使用的重复参数。这个例子case class Example(value: Option[String] = None, otherValues: Any*) 有不同的类型,但仍然遇到同样的问题

    【讨论】:

    • 对,完全有道理。阅读答案后,似乎很明显,我自己没有弄清楚它有点愚蠢:)
    • 这种歧义只是你想要的歧义。例如,您的示例在 Ruby 中工作得非常好,而 Ruby 甚至没有引导它的类型的优势。 Ruby 甚至在(位置)参数列表的开头和结尾都允许强制位置参数。基本上,开头的强制位置参数首先从左到右绑定,然后在末尾从右到左绑定强制位置参数,然后是从左到右的可选位置参数,然后是其余位置参数。
    • 所有这些后面都是强制关键字参数,可选关键字参数,最后是rest关键字参数。因此,原因不一定是“它不能明确”,而是“使其明确不适合其他语言的简单性”。所以,"Hello" 绑定到 valueSeq("world") 绑定到 otherValues,如果我们遵循 Ruby 规则,并且没有歧义。
    • @JörgWMittag 我也是这个意思。这并不是说没有办法编写一个可以处理它的编译器。这是关于如果完成后将变得难以使用的规则。每种语言都有很多这样的地方。例如按返回类型重载属于同一类别。您可以允许这样做并在执行调用时通过所需类型找出确切的方法,但是编译器和开发人员这样做都很复杂,因此几乎没有语言决定允许这样做
    猜你喜欢
    • 2018-04-30
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    相关资源
    最近更新 更多