Я взглянул на список опросов, проведенных на scala-lang.org, и заметил интересный вопрос: « Можете ли вы назвать все случаи использования« _ »? ». Ты можешь? Если да, пожалуйста, сделайте это здесь. Пояснительные примеры приветствуются.
540
Ответы:
Те, о которых я могу думать,
Экзистенциальные типы
Более высокие параметры типа
Игнорируемые переменные
Игнорируемые параметры
Игнорируемые имена типов сам
Шаблоны подстановочных знаков
Шаблоны подстановочных знаков в интерполяциях
Подстановочный знак последовательности в шаблонах
Импорт подстановочных знаков
Сокрытие импорта
Присоединение писем к операторам
Операторы присваивания
Синтаксис заполнителя
Значения метода
Преобразование параметров по имени в функции
Инициализатор по умолчанию
Могут быть и другие, которые я забыл!
Пример, показывающий, почему
foo(_)
иfoo _
отличаются:Этот пример взят из 0__ :
В первом случае
process _
представляет метод; Scala использует полиморфный метод и пытается сделать его мономорфным, заполнив параметр типа, но понимает, что не существует типа, который можно заполнитьA
, чтобы получить тип(_ => Unit) => ?
(Existential_
не является типом).Во втором случае
process(_)
- лямбда; когда пишется лямбда без явного типа аргумента, Scala выводит тип из ожидаемого аргументаforeach
и_ => Unit
является типом (тогда как просто_
не является), поэтому он может быть заменен и выведен.Это может быть самая хитрая ошибка в Scala, с которой я когда-либо сталкивался.
Обратите внимание, что этот пример компилируется в 2.13. Проигнорируйте это, как это было назначено, чтобы подчеркнуть.
источник
val x: Any = _
println _
иprintln(_)
разные. Вы можете видеть это, например, в том, что они обрабатывают экзистенциальный и полиморфный типы немного по-разному. Придумаем пример чуть позже.Из (моей записи) в FAQ , который я, конечно, не гарантирую, чтобы быть полным (я добавил две записи всего два дня назад):
Это тоже часть этого вопроса .
источник
var i: Int = _
или особый случай сопоставления с образцомval (a, _) = (1, 2)
или особый случай отбрасывания valfor (_ <- 1 to 10) doIt()
def f: T; def f_=(t: T)
комбо для создания изменяемого члена f._
имена методов - обман. Но, хорошо, хорошо. Я просто надеюсь, что кто-то еще обновит FAQ ... :-)Отличным объяснением использования подчеркивания является Scala _ [underscore] magic .
Примеры:
В Scala
_
действует аналогично*
Java при импорте пакетов.В Scala геттер и сеттер будут неявно определены для всех не приватных переменных в объекте. Имя получателя совпадает с именем переменной и
_=
добавляется для имени установщика.Применение:
Если вы попытаетесь присвоить функцию новой переменной, она будет вызвана и результат будет присвоен переменной. Эта путаница возникает из-за необязательных скобок для вызова метода. Мы должны использовать _ после имени функции, чтобы присвоить ее другой переменной.
источник
List(1,2,3,4,5).foreach(print(_))
это гораздо удобнее для чтенияList(1,2,3,4,5).foreach(print)
, вам даже не нужно подчеркивание, но я думаю, это просто вопрос стиляЕсть одно использование, которое я вижу, что все здесь, кажется, забыли перечислить ...
Вместо того, чтобы делать это:
Вы можете просто сделать это:
источник
n => n
Вот еще несколько примеров, где
_
используется:Во всех приведенных выше примерах одно подчеркивание представляет элемент в списке (для уменьшения первое подчеркивание представляет аккумулятор)
источник
Помимо использований , что Хайро упомянул, мне нравится это:
Если кому-то нужны все свойства соединения, он может сделать:
Если вам нужен только хост и порт, вы можете сделать:
источник
Существует конкретный пример использования _:
может быть равно:
Применение «_» в некоторых сценариях автоматически преобразует в «(x $ n) => x $ n»
источник