Scala lecture #4
-
Upload
alexander-podkhalyuzin -
Category
Documents
-
view
286 -
download
0
Transcript of Scala lecture #4
![Page 1: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/1.jpg)
Scala #4Scopes, XML, Scala type system
![Page 2: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/2.jpg)
Scopes
Scopes - это место в коде, где может быть объявлена переменная. ● { - начинает новый scope, кроме классов ● Каждый генератор в for statement
начинает новый scope ● Функция начинает новый scope для
параметров ● Case clause начинает новый scope Переменная объявленная внутри одного scope не видна снаружи.
![Page 3: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/3.jpg)
Names shadowing
Во внутреннем scope можно скрывать имя определенное во внешнем scope при условии, что приоритет этого имени не ниже чем у имени объявленного снаружи.
Это ошибка объявить переменные с одним именем внутри одного и того же scope.
Существует два вида имен: expressions, types.
![Page 4: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/4.jpg)
Think functional
Давайте напишем программу вывода таблицы умножения (см. Programming Scala)
![Page 5: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/5.jpg)
Initialization
Инициализация происходит в обратом порядке, нежели линеаризация. Порядок важно понимать, иначе можно заработать NullPointerException:
![Page 6: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/6.jpg)
Initializationobject InitializationNPE {
class A {
val x1 = "text"
val x2 = x1.length
}
class B extends A {
override val x1 = "text1"
}
def main(args: Array[String]) {
new B
}
}
![Page 7: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/7.jpg)
Initialization
Есть два способа решить эту проблему● Early definitions● Lazy initialization
![Page 8: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/8.jpg)
Early definitions
Если нужно определить что-то до вызова super конструктора, это можно сделать в early definitions:
class B(x: Int)
class A(s: String) extends {
val i = s.toInt
} with B(i * i)
![Page 9: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/9.jpg)
Initialization (early defs)object InitializationNPE {
class A {
val x1 = "text"
val x2 = x1.length
}
class B extends {
override val x1 = "text1"
} with A
def main(args: Array[String]) {
new B
}
}
![Page 10: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/10.jpg)
Lazy values
Scala поддерживает синтиаксис ленивых вычислений. От пользователя требуется лишь объявить переменную, как lazy.
Реализация double-checked locking, что приводит к определенным сложностям.
![Page 11: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/11.jpg)
Initialization (lazy vals)object InitializationNPE {
class A {
lazy val x1 = "text"
val x2 = x1.length
}
class B extends A {
override lazy val x1 = "text1"
}
def main(args: Array[String]) {
new B
}
}
![Page 12: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/12.jpg)
Few words about traits
Как же компилируются traits, рассмотрим простой пример:
trait Base {
def foo() = 1
}
class Child extends Base
![Page 13: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/13.jpg)
Few words about traitspublic interface Base {
int foo();
}
public class Base$class {
public static int foo(Base base) {
return 1;
}
}
public class Child implements Base {
public int foo() {
return Base$class.foo(this);
}
}
![Page 14: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/14.jpg)
Embedded XML
Практически любой валидный XML можно использовать как литерал:
val xml1 = <a>Some text<b/></a>val xml2 = <a>{3 + 4}</a>val xml3 = <a>{"</a>It's just String<a>"}</a>
Если надо написать {, то его можно заэскейпить {{.
![Page 15: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/15.jpg)
XML API
Базовый класс scala.xml.Node.Доступ к subelement через \ “name”.К аттрибутам через \ “@name”.Рекурсивный поиск в глубину \\ “name”.
val xml = <a id="text"><b>S<c></c></b></a>
xml.text // S
xml \ "b" // <b>S<c></c></b>
xml \ "@id" // text
xml \\ "c" // <c></c>
![Page 16: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/16.jpg)
Using XML
Встроенный XML легко использовать для сериализации:
val node = <x></x>
scala.xml.XML.save("File.xml", node)
scala.xml.XML.load("File.xml")
![Page 17: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/17.jpg)
Pattern matching
В pattern matching есть особый синтаксис для XML:
val node = <x></x>
scala.xml.XML.save("File.xml", node)
scala.xml.XML.load("File.xml")
![Page 18: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/18.jpg)
Scala type system
![Page 19: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/19.jpg)
Basic types
● Primitive types● Type designators● Parameterized types● Tuple types● Function types● Infix types● Type projections● Singleton types● Annotated types
![Page 20: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/20.jpg)
Advanced types
● Structural types● Existential types● Method types (internal type)● Polymorphic method types (internal type)● Type constructors (internal type)
![Page 21: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/21.jpg)
Primitive types
Есть несколько важных фич:● Numeric Widening. Если работает weak
conformance, то он автоматический.● Literal Narrowing. Literal с ожидаемым
типом Byte, Short or Char конвертируется.● Value discarding. Если тип Uеnit, то для
любого выражения, есть конверсия.Value classes также наследуются от AnyVal.
![Page 22: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/22.jpg)
Type designators
Это просто любой class, trait или object как тип. Ничего особенного здесь не подразумевается.
![Page 23: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/23.jpg)
Parameterized types
Для type designator и его type parameters есть два правила:● Число type parameters должно of underli
совпадать с числом параметорв соответствующего класса type designator.
● Каждый type parameter должен подходить к type parameter bounds
![Page 24: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/24.jpg)
Tuple types
Синтаксический сахар для TupleN[T1, ..., Tn] типа. Subtyping разрешается также, как и subtyping соответствующего TupleN класс согласно вариантности.Поэтому этот код и не скомпилируется:
object A {
def foo(x: (Int, Int)) = x._1 + x._2
def foo(x: (String, String)) = x._1 + x._2
}
![Page 25: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/25.jpg)
Automatic tupling
Позволяет избежать лишних скобок, особенно это полезно для infix нотации.
object A {
def foo(x: (Int, Int)) = x._1 + x._2
}
A.foo((1, 2))
A.foo(1, 2)
A foo (1, 2)
println(1, 2, 3)
![Page 26: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/26.jpg)
Function type
Уже подробно изученный нами синтаксический сахар. В силу недосмотра в компиляторе это несовсем синтаксический сахар:
val x1: Function1[Int, Int] = x => x + 1
val x2: Int => Int = _ + 1
val y1: Function1[Seq[Int], Int] = x => x.length
val y2: (Int*) => Int = x => x.length
![Page 27: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/27.jpg)
Annotated types
Любой тип можно проаннотировать. С точки зрения системы типов эта аннотация будет проигнорирована:
class A
val a: A @serializable = new A
![Page 28: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/28.jpg)
Infix types
Синтаксический сахар (опять?..)
class :::[T, S]
val x: :::[Int, Int] = new :::
val y: Int ::: Int = new :::
![Page 29: Scala lecture #4](https://reader033.fdocuments.net/reader033/viewer/2022052912/55a0a68a1a28ab64778b4750/html5/thumbnails/29.jpg)
Infix types
Может быть полезно для операторов над типами:
type n[A] = A => Nothing
type ++[T, U] = n[n[T] with n[U]]
type nn[A] = n[n[A]]
type |+|[T, U] = { type λ[X] = nn[X] <:< (T ++ U) }
def size[T : (Int |+| String)#λ] (t: T) = t match {
case i: Int => i
case s: String => s.length
}