Каковы варианты использования синтаксиса Ignored Variable в Scala?
В соответствии с этим ответом qaru.site/info/1380/... мы можем сделать это в Scala:
val _ = 5
Теперь я понимаю точку игнорируемых параметров в лямбда-выражениях, но я не могу представить себе примеры, где я бы хотел объявить переменную, которую по определению я не могу ссылаться. Единственный пример, который я могу придумать, - это лениться в том, чтобы именовать неявные значения, например.
implicit val _: MyNumeric = ...
...
class A[T : MyNumeric] {
...
Это единственный случай использования? Я что-то пропустил?
Если это единственный случай использования, не должен ли компилятор /IDE давать предупреждение/подсказку, когда val
не является неявным, поскольку он совершенно бессмысленен?
Разъяснение
По переменной/значению я подразумеваю один, а не один, который является частью объявления извлечения.
Ответы
Ответ 1
Он использует значение.
$ scala -Ywarn-value-discard
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def f() = { println("I ran.") ; 42 }
f: ()Int
scala> def g(): Unit = { f() }
<console>:8: warning: discarded non-Unit value
def g(): Unit = { f() }
^
g: ()Unit
scala> def g(): Unit = { val _ = f() }
g: ()Unit
scala> g
I ran.
scala>
Чтобы убедиться, он также не предупреждает в -Ywarn-unused
.
Ответ 2
Я не думаю, что это вообще функция. В любом случае это не "игнорируемая переменная".
Под этим я подразумеваю, что если val _ = 5
действительно введено неназванное значение, вы можете объявить столько, сколько хотите в одной и той же области.
Не так:
scala> object Test {
| val _ = 5
| val _ = 7
| }
<console>:9: error: _ is already defined as value _
val _ = 7
^
Из сообщения об ошибке кажется, что действительно происходит то, что на самом деле это значение называется _
(который я бы назвал причудой компилятора, который должен быть исправлен). Мы можем проверить это:
scala> object Test {
| val _ = 5
| def test() { println( `_` ) } // This compiles fine
| }
defined object Test
scala> Test.test()
5
Что касается возможного использования предупреждения о сбросе значения (как показано в ответе som-snytt), я предпочитаю просто возвращать явный Unit
.
Это выглядит менее запутанным и даже короче:
def g(): Unit = { f(); () }
в отличие от:
def g(): Unit = { val _ = f() }
Ответ 3
Другой вариант использования (что я могу придумать) связан с извлечением (и вызывается под "шаблонами подстановочных знаков" в связанном ответе):
val getCartesianPoint = () => (1, 2, 3)
// We don't care about the z axis, so we assign it to _
val (x, y, _) = getCartesianPoint()
val regex = "(.*?)|(.*?)|?.*".r
// Really, any unapply or unapplySeq example will do
val regex(_, secondValue) = "some|delimited|value|set"