Подтвердить что ты не робот

В сопоставлении с шаблоном scala, что такое подозрительное затенение с помощью шаблона переменной?

Когда я ввожу следующий код в Intellij, он выделяет x внутри матча с предупреждением "Подозрительное затенение с помощью шаблона переменной"

val x = "some value"
"test" match {
  case x =>
}

Это говорит о том, что я меняю его на:

val x = "some value"
"test" match {
  case `x` => //note backticks
}

Что такое подозрительное затенение и что делают backticks?!

4b9b3361

Ответ 1

case x

создает переменную с именем x, которая соответствовала бы всем, и поскольку уже существует переменная с тем же именем, вы затеняете ее, используя одно и то же имя.

case `x`

использует значение переменной x, которое было объявлено ранее, и будет соответствовать только входам с одинаковыми значениями.

PS

Вы можете оставить обратные тики, если имя переменной заглавны, как в

case Pi

Ответ 2

Выдержка из программирования в Scala [1]:

Литеральный идентификатор - это произвольная строка, заключенная в обратные тики (`...`). Некоторые примеры буквенных идентификаторов:

    `x` `<clinit>` `yield`

Идея состоит в том, что вы можете поместить любую строку, принятую во время выполнения, в качестве идентификатора между обратными тиками. Результатом всегда является идентификатор Scala. Это работает, даже если имя, содержащееся в обратных тиках, будет Scala зарезервированным словом. Типичным примером использования является доступ к статическому методу yield в классе Java Thread. Вы не можете написать Thread.yield(), потому что yield является зарезервированным словом в Scala. Однако вы все равно можете называть метод обратными тиками, например Thread.`yield`().

Короче говоря, с `x` вы сопоставляетесь со значением x. С помощью x вы создаете новую переменную, которая будет соответствовать чему-либо, и сохраните результат до x.

[1] M. Odersky, L. Spoon, B. Venners, Programming in Scala, 2nd ed, Walnut Creek: Artima Press 2010, pp. 109 http://www.artima.com/pins1ed/functional-objects.html#i1517246665-1

Ответ 3

Случай внутри матча генерирует новый символ x для получения согласованного значения. Это связано с тем, что, согласно соглашениям, ожидается, что идентификаторы нижних регистров будут ссылаться на значения и идентификаторы верхнего регистра на типы.

Таким образом, оператор case генерирует новый символ с тем же именем x в качестве вашего начального значения, "затеняя" это исходное значение. "Затенение" IntelliJ означает, что он скрывает любые другие значения с тем же именем и, следовательно, делает их недоступными.

Он помещает это как подозрительное, потому что это затенение часто бывает непреднамеренным, что, по-видимому, имеет место в вашем примере.

Что касается обратных выходов, см., например, здесь: Требуется уточнение для Scala литеральных идентификаторов (обратных ссылок) Тем не менее, они не кажутся хорошим решением. Лучше выбрать другое имя.