Scala Cheatsheet
Scala Cheatsheet
Language
Contributed by Dima Kotobotov
Эта шпаргалка создана благодаря Brendan O’Connor и предназначена для быстрого ознакомления с синтаксическими конструкциями Scala. Лицензия выдана Brendan O’Connor по лицензии CC-BY-SA 3.0.
переменные | |
var x = 5 |
переменная |
Хорошоval x = 5 Плохо x=6 |
константа |
var x: Double = 5 |
явное указание типа |
функции | |
Хорошоdef f(x: Int) = { x*x } Плохо def f(x: Int) { x*x } |
объявление функции незаметная ошибка: без = это процедура с возвращаемым типом "Unit". Такое может ввести в заблуждение |
Хорошоdef f(x: Any) = println(x) Плохо def f(x) = println(x) |
объявление функции синтаксическая ошибка: для каждого аргумента необходимо указывать его тип. |
type R = Double |
псевдоним для типа |
def f(x: R) vs.def f(x: => R) |
вызов по значению вызов по имени (вычисление аргумента отложено) |
(x:R) => x*x |
анонимная функция |
(1 to 5).map(_*2) vs.(1 to 5).reduceLeft( _+_ ) |
анонимная функция: подчеркивание указывает место подставляемого элемента. |
(1 to 5).map( x => x*x ) |
анонимная функция: слева от => задается имя подставляемого элемента, чтоб его можно было переиспользовать |
Хорошо(1 to 5).map(2*) Плохо (1 to 5).map(*2) |
анонимная функция: запись с использованием инфиксного стиля. Ради четкого понимания лучше использовать явное указание позиции подставляемого элемента в стиле 2*_ . |
(1 to 5).map { x => val y=x*2; println(y); y } |
анонимная функция: стиль блоковой передачи (фигурные скобки обозначают блок), возвращается последнее значение (y). |
(1 to 5) filter {_%2 == 0} map {_*2} |
анонимные функции: конвейерный стиль. В однострочных выражениях можно использовать простые скобки. |
def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x)) val f = compose({_*2}, {_-1}) |
анонимные функции: передача блоков в качестве аргументов |
val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd |
каррирование, явный синтаксис. |
def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd |
каррирование, явный синтаксис |
def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd |
каррирование, синтаксический сахар. Но если : |
val normer = zscore(7, 0.4) _ |
следом использовать подчеркивание, то мы получим частично определенную функцию. |
def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g) |
обобщенный тип. |
5.+(3); 5 + 3 (1 to 5) map (_*2) |
инфиксный стиль. |
def sum(args: Int*) = args.reduceLeft(_+_) |
функция с переменным числом аргументов. |
пакеты | |
import scala.collection._ |
импорт всех членов пакета. |
import scala.collection.Vector import scala.collection.{Vector, Sequence} |
выборочный импорт. |
import scala.collection.{Vector => Vec28} |
импорт с переименованием. |
import java.util.{Date => _, _} |
импортировать все из java.util кроме Date. |
package pkg в самом начале файла package pkg { ... } |
объявление пакета. |
структуры данных | |
(1,2,3) |
кортеж размера 3. (Tuple3 ) |
var (x,y,z) = (1,2,3) |
разложение на отдельные элементы: кортеж раскладывается на элементы x, y и z используя сопоставление с образцом. |
Плохоvar x,y,z = (1,2,3) |
незаметная ошибка: каждой переменной будет присвоено по кортежу. |
var xs = List(1,2,3) |
список (неизменяемый). |
xs(2) |
получение элемента по индексу в скобках. (примеры) |
1 :: List(2,3) |
добавление к списку. |
1 to 5 тоже что и 1 until 6 1 to 10 by 2 |
задание диапазона (синтаксический сахар). |
() (пустые скобки) |
одиночный член типа Unit (тоже что и void в C/Java). |
управляющие структуры | |
if (check) happy else sad |
условие. |
if (check) happy
тоже что и if (check) happy else () |
синтаксический сахар (ветка else добавляется автоматически). |
while (x < 5) { println(x); x += 1} |
цикл с условием в блоке while . |
do { println(x); x += 1} while (x < 5) |
цикл с условием и обязательным исполнением в блоке do. |
|
выход из цикла с использованием break. (примеры) |
for (x <- xs if x%2 == 0) yield x*10
тоже что и xs.filter(_%2 == 0).map(_*10) |
for-выражение: выражается набором с filter/map |
for ((x,y) <- xs zip ys) yield x*y
тоже что и (xs zip ys) map { case (x,y) => x*y } |
for-выражение: извлечение элементов с последующим вычислением |
for (x <- xs; y <- ys) yield x*y
тоже что и xs flatMap {x => ys map {y => x*y}} |
for-выражение: перекрестное объединение |
|
for-выражение: императивно sprintf-style |
|
for-выражение: обход диапазона (от 1 до 5) включая его верхнюю границу |
|
for-выражение: обход диапазона (от 1 до 5) не включая его верхнюю границу |
сопоставление с примером | |
Хорошо(xs zip ys) map { case (x,y) => x*y } Плохо (xs zip ys) map( (x,y) => x*y ) |
используйте ключевое слово case при передачи аргументов в функцию для запуска механизма сопоставления с примером. |
Плохо
|
“v42” интерпретировано как имя для новой константы любого типа, поэтому напечатано “42”. |
Хорошо
|
”`v42`” с обратными кавычками интерпретируется как указание на значение существующей константы v42 , напечатано “Not 42”. |
Хорошо
|
UppercaseVal однако константы, имена которых начинаются с заглавной буквы, сопоставляются по значению. Поэтому при сопоставлении UppercaseVal с 3 , выводится “Not 42”. |
Работа с объектами | |
class C(x: R) |
параметр конструктора - x доступен только внутри тела класса |
class C(val x: R) var c = new C(4) c.x |
параметр конструктора - доступен публично, автоматически |
|
конструктор является телом класса объявление публичного члена класса объявление члена с гетером но без сеттера объявление приватного члена объявление альтернативного конструктора без аргумента |
new{ ... } |
анонимный класс |
abstract class D { ... } |
объявление абстрактного класса (не создаваемого, только наследуемого) |
class C extends D { ... } |
объявление класса с наследованием. |
class D(var x: R) class C(x: R) extends D(x) |
наследование класса с конструированием параметров. |
object O extends D { ... } |
объявление объекта одиночки (Singleton) на основе другого класса. |
trait T { ... } class C extends T { ... } class C extends D with T { ... } |
трейты описывают какие функции и данные должны быть в классе, возможно также указание конкретной (или общей) реализации а также указание значений переменных. у трейта нет конструктора. их можно смешивать. |
trait T1; trait T2 class C extends T1 with T2 class C extends D with T1 with T2 |
множественные трейты. |
class C extends D { override def f = ...} |
при наследовании и создании методов с одинаковыми именами необходимо указывать override. |
new java.io.File("f") |
создание объекта. |
Плохоnew List[Int] Хорошо List(1,2,3) |
ошибка: List - это абстрактный класс по соглашению используется объект с именем как у абстрактного класса, который уже создает конкретные экземпляры |
classOf[String] |
описание класса. |
x.isInstanceOf[String] |
проверка типа (при исполнении) |
x.asInstanceOf[String] |
приведение типа (при исполнении) |
x: String |
приписывание типа (во время компиляции) |