diff --git a/_overviews/cheatsheets/index.md b/_overviews/cheatsheets/index.md index aa27d9e403..b59d3fcdcf 100644 --- a/_overviews/cheatsheets/index.md +++ b/_overviews/cheatsheets/index.md @@ -7,7 +7,7 @@ partof: cheatsheet by: Brendan O'Connor about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. -languages: [ba, fr, ja, pl, pt-br, zh-cn, th] +languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru] permalink: /cheatsheets/index.html --- diff --git a/_ru/cheatsheets/index.md b/_ru/cheatsheets/index.md new file mode 100644 index 0000000000..83d2e9d7c4 --- /dev/null +++ b/_ru/cheatsheets/index.md @@ -0,0 +1,357 @@ +--- +layout: cheatsheet +title: Scalacheat + +partof: cheatsheet + +by: Dima Kotobotov +about: Эта шпаргалка создана благодаря Brendan O'Connor и предназначена для быстрого ознакомления с синтаксическими конструкциями Scala. Лицензия выдана Brendan O'Connor по лицензии CC-BY-SA 3.0. + +language: ru +--- + +###### Contributed by {{ page.by }} +{{ page.about }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
переменные
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.
import scala.util.control.Breaks._
+breakable {
+  for (x <- xs) {
+    if (Math.random < 0.1)
+      break
+  }
+}
выход из цикла с использованием 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 (x <- xs; y <- ys) {
+  println("%d/%d = %.1f".format(x, y, x/y.toFloat))
+}
for-выражение: императивно
sprintf-style
for (i <- 1 to 5) {
+  println(i)
+}
for-выражение: обход диапазона (от 1 до 5) включая его верхнюю границу
for (i <- 1 until 5) {
+  println(i)
+}
for-выражение: обход диапазона (от 1 до 5) не включая его верхнюю границу
сопоставление с примером
Хорошо
(xs zip ys) map { case (x,y) => x*y }
Плохо
(xs zip ys) map( (x,y) => x*y )
используйте ключевое слово case при передачи аргументов в функцию для запуска механизма сопоставления с примером.
Плохо
+
val v42 = 42
+Some(3) match {
+  case Some(v42) => println("42")
+  case _ => println("Not 42")
+}
“v42” интерпретировано как имя для новой константы любого типа, поэтому напечатано “42”.
Хорошо
+
val v42 = 42
+Some(3) match {
+  case Some(`v42`) => println("42")
+  case _ => println("Not 42")
+}
”`v42`” с обратными кавычками интерпретируется как указание на значение существующей константы v42, напечатано “Not 42”.
Хорошо
+
val UppercaseVal = 42
+Some(3) match {
+  case Some(UppercaseVal) => println("42")
+  case _ => println("Not 42")
+}
UppercaseVal однако константы, имена которых начинаются с заглавной буквы, сопоставляются по значению. Поэтому при сопоставлении UppercaseVal с 3, выводится “Not 42”.
Работа с объектами
class C(x: R)параметр конструктора - x доступен только внутри тела класса
class C(val x: R)
var c = new C(4)
c.x
параметр конструктора - доступен публично, автоматически
class C(var x: R) {
+  assert(x > 0, "positive please")
+  var y = x
+  val readonly = 5
+  private var secret = 1
+  def this() = this(42)
+}
конструктор является телом класса
объявление публичного члена класса
объявление члена с гетером но без сеттера
объявление приватного члена
объявление альтернативного конструктора без аргумента
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приписывание типа (во время компиляции)
\ No newline at end of file