відмова від відповідальності: частини цих відповідей - це узагальнення інших відповідей, знайдених тут.
Використовуйте лямбда, не вказуючи їхні типи аргументів
Дозволяється подавати щось подібне: 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)
.
Використовуйте функцію curried, коли вам потрібні два аргументи.
(a,b)=>... //wrong
a=>b=>... //right
Використовуйте _
-синтаксис, коли це можливо
Правила цього дещо незрозумілі, вам доведеться трохи пограти навколо, щоб знайти найкоротший шлях.
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
Використовуйте рядки як послідовності
""
іноді це найкоротший спосіб створити порожню послідовність, якщо вам не байдужий тип актуальної форми
Використовуйте 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
Скористайтеся потоком для нескінченних послідовностей
Деякі проблеми задають n-й елемент нескінченної послідовності. Потік - ідеальний кандидат для цього. Пам'ятайте 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
вони коротші.