我发现了scala的这个问题:https://issues.scala-lang.org/browse/SI-4939
似乎我们可以定义一个名称为数字的方法:
scala> object Foo { val 1 = 2 }
defined module Foo
但我们无法援引它:
scala> Foo.1
<console>:1: error: ';' expected but double literal found.
Foo.1
我们可以在对象中调用它:
scala> object O { val 1 = 1; def x = 1 }
defined module O
scala> O.x
res1: Int = 1
然后将抛出错误:
scala> object O { val 1 = 2; def x = 1 }
defined module O
scala> O.x
scala.MatchError: 2
at O$.<init>(<console>:5)
at O$.<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:9)
我使用scalac -Xprint:typer
查看代码,val 1 = 2
部分是:
<synthetic> private[this] val x$1: Unit = (2: Int(2) @unchecked) match {
case 1 => ()
}
从中我们可以看到方法名称已更改为x$1
,并且只能在该对象内调用。
该问题的解决方案是:无法修复
我想知道是否有理由允许数字作为方法的名称?有什么情况我们需要使用“数字”方法吗?
答案 0 :(得分:10)
此处没有绑定名称“1
”。 val 1 = 2
是模式匹配表达式,与val (x,2) = (1,2)
将x
绑定到1的方式大致相同(如果第二个元素不相同,则会抛出MatchError
。这是允许的,因为没有真正的理由来添加特殊情况来禁止它;这种方式val
模式匹配(几乎)与match
模式匹配完全相同。
答案 1 :(得分:4)
这种决定通常有两个因素:
Scalac中存在许多优先级较高的错误,并且错误修复资源有限。此行为是良性的,因此优先级较低。
语言规范的复杂性增加会带来长期成本,而且当前的行为与规范一致。一旦事情开始变得特殊,就会出现雪崩效应。
这是这两者的一些组合。
更新。这对我来说似乎很奇怪:
val pair = (1, 2)
object Foo
object Bar
val (1, 2) = pair // Pattern matching on constants 1 and 2
val (Foo, Bar) = pair // Pattern matching on stable ids Foo and Bar
val (foo, bar) = pair // Binds foo and bar because they are lowercase
val 1 = 1 // Pattern matching on constant 1
val Foo = 1 // *Not* pattern matching; binds Foo
如果val 1 = 1
是模式匹配,那么为什么val Foo = 1
绑定Foo
而不是模式匹配?
更新2 。 Daniel Sobral指出这是一个特殊的例外,而Martin Odersky最近wrote the same。
答案 2 :(得分:1)
以下是一些示例,说明作业的LHS如何不仅仅是一个名称:
val pair = (1, 2)
val (a1, b1) = pair // LHS of the = is a pattern
val (1, b2) = pair // okay, b2 is bound the the value 2
val (0, b3) = pair // MatchError, as 0 != 1
val a4 = 1 // okay, a4 is bound to the value 1
val 1 = 1 // okay, but useless, no names are bound
val a @ 1 = 1 // well, we can bind a name to a pattern with @
val 1 = 0 // MatchError
答案 3 :(得分:0)
与往常一样,您可以使用反引号来逃避名称。我认为支持这些名称没有问题 - 要么你使用它们,它们适合你,要么它们不能为你工作,你就不会使用它们。