Отказ от ответственности: части этих ответов являются обобщением других ответов, найденных здесь.
Используйте лямбды без указания их аргументов
Допускается отправлять что-то вроде этого: a=>a.size
вместо (a:String)=>a.size
.
Используйте ascii-символы в качестве идентификаторов.
К ним относятся !%&/?+*~'-^<>|
. Поскольку они не являются буквами, их разбирают, когда они рядом с буквами.
Примеры:
a=>b //ok
%=>% //error, parsed as one token
% => % //ok
val% =3 //ok
&contains+ //ok
if(x)&else* //ok
Используйте Set вместо содержит
if (Seq(1,2,3,'A')contains x)... //wrong
if (Set(1,2,3,'A')(x))... //right
Это возможно потому что Set[A] extends (A => Boolean)
.
Используйте функцию карри, когда вам нужно два аргумента.
(a,b)=>... //wrong
a=>b=>... //right
Используйте _
-syntax, когда это возможно
Правила для этого несколько неясны, иногда нужно немного поиграть, чтобы найти кратчайший путь.
a=>a.map(b=>b.size)) //wrong
a=>a.map(_.size) //better
_.map(_.size) //right
Использовать частичное применение
a=>a+1 //wrong
_+1 //better, see above
1+ //right; this treats the method + of 1 as a function
Используйте ""+
вместоtoString
a=>a.toString //wrong
a=>a+"" //right
Используйте строки как последовательности
""
иногда самый короткий способ создать пустую последовательность, если вам не важен тип actula
Используйте BigInt для преобразования чисел в и из строк
Самый короткий способ преобразовать число в строку в базе, отличной от базы 10, - это toString(base: Int)
метод BigInt.
Integer.toString(n,b) //wrong
BigInt(n)toString b //right
Если вы хотите преобразовать строку в число, используйте BigInt.apply(s: String, base: Int)
Integer.parseInt(n,b) //wrong
BigInt(n,b) //right
Имейте в виду, что это возвращает BigInt, который может использоваться как число в большинстве случаев, но не может использоваться, например, как индекс для последовательности.
Используйте Seq для создания последовательностей
a::b::Nil //wrong
List(...) //also wrong
Vector(...) //even more wrong
Seq(...) //right
Array(...) //also wrong, except if you need a mutable sequence
Используйте строки для последовательности символов:
Seq('a','z') //wrong
"az" //right
Используйте Stream для бесконечных последовательностей
Некоторые проблемы требуют n-го элемента бесконечной последовательности. Stream является идеальным кандидатом для этого. Помните Stream[A] extends (Int => A)
, что поток - это функция от индекса до элемента с этим индексом.
Stream.iterate(start)(x=>calculateNextElement(x))
Используйте символические операторы вместо своих многословных аналогов
:\
и :/
вместо foldRight
иfoldLeft
a.foldLeft(z)(f) //wrong
(z/:a)(f) //right
a.foldRight(z)(f) //wrong
(a:\z)(f) //right
hashCode
-> ##
throw new Error()
-> ???
Используйте &
и |
вместо &&
и||
Они работают одинаково для логических значений, но всегда будут оценивать оба операнда
Псевдоним длинный метод как функции
def r(x:Double)=math.sqrt(x) //wrong
var r=math.sqrt _ //right; r is of type (Double=>Double)
Знать функции в стандартной библиотеке
Особенно это относится к методам коллекций.
Очень полезные методы:
map
flatMap
filter
:/ and :\ (folds)
scanLeft and scanRight
sliding
grouped (only for iterators)
inits
headOption
drop and take
collect
find
zip
zipWithIndex3
distinct and/or toSet
startsWith
#define
например, но я признаю, что это приятноdef
иval
короче.