Статьи

Фрагменты Scala 2: список символов магии

Также доступны следующие другие фрагменты:

  1. Отрывки Scala 1: складные

В scala каждый символ может быть функцией, поэтому перегрузка операторов (которая на самом деле не перегружается, поскольку операторы уже являются методами) очень проста, и это то, что вы видите во многих библиотеках. В этом фрагменте мы просто рассмотрим несколько перегруженных методов, которые значительно упрощают работу со списками.

Итак, давайте начнем и посмотрим на оператор ++. Во-первых, как мы всегда делаем, давайте создадим список.

1
2
3
4
5
scala> val list = 0 until 10 toList
list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

И просто пройдитесь по операторам отсюда: http://www.scala-lang.org/api/2.11.1/index.html#scala.collection.immutab…

Первый оператор, который мы рассмотрим, это ++. С помощью этого оператора мы можем добавить два списка вместе и вернуть новый:

1
2
3
4
5
scala> val list3 = list ++ list2
list3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  
scala> val list3 = list2 ++ list
list3: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Обратите внимание, что вам не нужно добавлять одинаковые типы. Scala автоматически выберет наиболее подходящий суперкласс.

01
02
03
04
05
06
07
08
09
10
11
scala> val list1 = 0 to 10 toList
list1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  
scala> val list3 = list1.asInstanceOf[List[Double]]
list3: List[Double] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> list3 ++ list2
res4: List[AnyVal] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

Как видите, AnyVal является наиболее распространенным супертипом как Int, так и Double, поэтому каждый выбирается.

Теперь, когда мы увидели оператор ++, давайте посмотрим на один почти такой же оператор ++:. С этим оператором мы имеем ту же семантику, что и ++, но на этот раз тип результата определяется правильным операндом, а не левый:

01
02
03
04
05
06
07
08
09
10
11
scala> vector1
res14: Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
  
scala> list1
res15: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> vector1 ++ list1
res16: scala.collection.immutable.Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> vector1 ++: list1
res17: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Следующие два оператора: + и + :. С помощью этих двух операторов мы можем добавить и добавить элемент в список:

1
2
3
4
5
scala> 999 +: list1
res27: List[Int] = List(999, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> list1 :+ 999
res28: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 999)

Просто верно? Обратите внимание, что: всегда находится на стороне списка (цель). То же самое касается оператора ++: мы видели ранее.

Что еще у нас есть? :: и :::. Оба эти оператора добавляют что-то в начало списка. Оператор :: добавляет один элемент, а оператор ::: добавляет полный список. Так что в основном они такие же, как оператор +: и ++. Основное изменение заключается в том, что ++ и +: могут использоваться с Traversable, а ::: и :: могут использоваться только со списком.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
scala> 11 +: list1
res38: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> list1
res39: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> 11 +: list1
res40: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> list2
res41: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  
scala> list1 ::: list2
res43: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

И тогда мы в значительной степени охватили все, кроме: \ и: /. Эти функции позволяют вам свернуть ( см. Здесь ) список. : \ складывается справа налево и: / складывается слева направо.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
scala> list1
res50: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  
scala> (1 /: list1)((r,i) => {println(i);i+r})
0
1
2
3
4
5
6
7
8
9
10
res51: Int = 56
  
scala> (list1 :\ 1)((i,r) => {println(i);i+r})
10
9
8
7
6
5
4
3
2
1
0
res52: Int = 56

Как видите, направление складывания определяет, будут ли элементы обрабатываться от начала до конца или назад.

И это все для этого небольшого фрагмента.

Ссылка: Фрагменты Scala 2: перечислите магию символов от нашего партнера JCG Йоса Дирксена в блоге Smart Java .