Есть ли передовая практика для другой? Я читал книгу Scala Odersky, et al. и кажется, что infix используется для многих функций API коллекций, тогда как точка зарезервирована для определенных пользователем функций.
Scala - инфикс против точечной нотации
Ответ 1
У меня лично нет жестких и быстрых правил для этого, но я обычно использую нотацию infix только с именами символических методов и точечной нотации для буквенно-цифровых символов.
Обозначение Infix делает более громоздкой модификацию кода позже. Вот несколько примеров.
Представьте, что у вас есть эта строка кода:
xs filter { f } map { g }
Предположим, что в какой-то момент времени вам нужно добавить конец toList
. Вы так выразились:
xs filter { f } map { g } toList
Это может привести к проблемам с точкой с запятой. Чтобы избежать этих проблем, вы либо положили точку с запятой, либо положили новую строку. На мой взгляд, оба варианта уродливы. Чтобы избежать всей этой бессмыслицы, я предпочитаю идти с xs.filter(f).map(g)
. Всегда проще рефакторировать этот синтаксис.
Другой пример: Скажем, в моем коде есть следующее:
if(foo contains bar) { ..
Скажем, мне нужно отменить условие. Если я изменю его следующим образом:
if(!foo contains bar) { ..
Облом. Это анализируется как (!foo).contains(bar)
. Не то, что мы хотели.
Или предположим, что вам нужно дополнительно добавить новое условие, и вы измените его так:
if(foo contains bar && cond) { ..
Еще один облом. Это анализируется как foo.contains(bar.&&(cond))
. Не то, что мы хотели, снова.
Конечно, вы могли бы добавить кучу круглых скобок, но это было бы уродливо и трудно читать/редактировать по сравнению с точечной нотацией.
Теперь все, что я сказал выше, относится и к именам символических методов. Однако символические методы выглядят неестественно при использовании с синтаксисом точек, и поэтому я предпочитаю синтаксис инфикса для них.
Одно исключение из приведенного выше руководства: внутренние DSL. Они обычно обрабатываются с осторожностью, чтобы не вызывать проблемы с анализом, если они написаны так, как это указано в их документации/примерах (в которых обычно используется инфиксная нотация).
Ответ 2
Это вопрос личных предпочтений. Ваше решение использовать один стиль или другое должно основываться на том, что делает ваш код наиболее читаемым.
Но обратите внимание, что возможность оставить точку и круглые скобки ограничена только некоторыми синтаксическими конструкциями, поэтому иногда вам просто нужно вернуться к их использованию.
Ответ 3
В официальной документации по сайту Scala есть хорошее руководство , в котором описывается правильная нотация инфиксного использования над точечной нотацией.
Обозначение суффикса:
names.toList
// is the same as
names toList // Unsafe, don't use!
Arity-1:
// right!
names foreach (n => println(n))
names mkString ","
optStr getOrElse "<empty>"
// wrong!
javaList add item
Функции более высокого порядка:
// wrong!
names.map (_.toUpperCase).filter (_.length > 5)
// right!
names map (_.toUpperCase) filter (_.length > 5)
Символические методы/Операторы:
// right!
"daniel" + " " + "Spiewak"
// wrong!
"daniel"+" "+"spiewak"
Ответ 4
Я обнаружил, что использование нотации infix для map
прекрасно работает, когда я создаю декартес с библиотекой cats. например:.
(fetchIt(1) |@| fetchIt(2) |@| fetchIt(3)).map(MyCaseClass)
вы можете избавиться от окружающих круглых скобок, например:
fetchIt(1) |@| fetchIt(2) |@| fetchIf(3) map MyCaseClass
и, на мой взгляд, второй вариант лучше читается. Полагаю, вкус. Просто хотел добавить стоимость моих двух центов.
Вышеупомянутое работает, потому что |
в "| @|" имеет более высокий приоритет, чем m
в "карте". Прочтите эту часть спецификации Scala lang, чтобы узнать подробнее:
Если в выражении имеется несколько операций инфикса, то операторы с более высоким приоритетом связывают более тесно, чем операторы с более низким старшинство.
http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations