выдает `object Foo {val 1 = 2}` в scala - PullRequest
7 голосов
/ 24 августа 2011

Я обнаружил эту проблему в 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, и только можетбыть вызванным внутри этого объекта.

И решение этой проблемы: Не удастся исправить

Я хочу знать, есть ли какая-либо причина, чтобы число былоназвание метода?Есть ли случаи, когда нам нужно использовать «числовой» метод?

Ответы [ 4 ]

10 голосов
/ 24 августа 2011

Здесь нет названия "1". val 1 = 2 является выражением сопоставления с образцом, во многом таким же образом val (x,2) = (1,2) связывает x с 1 (и выкинет MatchError, если второй элемент не будет таким же). Это разрешено, потому что нет никакой реальной причины добавлять специальный случай, чтобы запретить это; таким образом val сопоставление с образцом работает (почти) точно так же, как match сопоставление с образцом.

4 голосов
/ 24 августа 2011

Обычно в принятии такого рода решений есть два фактора:

  1. В Scalac есть много ошибок, которые имеют гораздо более высокий приоритет, и ресурсы для исправления ошибок ограничены.Это поведение является доброкачественным и, следовательно, низким приоритетом.

  2. Существует долгосрочная плата за любое увеличение сложности языковой спецификации, и текущее поведение соответствует спецификации.Как только вещи начинают поступать в особом корпусе, может возникнуть лавинный эффект.

Это некоторая комбинация этих двух.


Обновление .Вот что мне кажется странным:

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 bind Foo, а не сопоставление с шаблоном?

Обновление 2.Даниэль Собрал отметил, что это особое исключение, и Мартин Одерский недавно написал то же самое .

1 голос
/ 25 августа 2011

Вот несколько примеров, чтобы показать, что 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
0 голосов
/ 24 августа 2011

Как всегда, вы можете использовать обратные кавычки, чтобы избежать имени.Я не вижу проблем в поддержке таких имен - либо вы используете их, и они работают на вас, либо они не работают на вас, а вы их не используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...