Tour of Scala

Выведение Типа

Language

Компилятор Scala часто может вывести тип выражения, так что вам не нужно указывать его явным образом.

Не указывая тип

val businessName = "Montreux Jazz Café"

Компилятор может определить, что тип константы businessName является String. Аналогичным образом это работает и для методов:

def squareOf(x: Int) = x * x

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

Для рекурсивных методов компилятор не в состоянии вывести тип. Вот программа, которая не скомпилируется по этой причине:

def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
def fac(n: Int) = if n == 0 then 1 else n * fac(n - 1)

Также необязательно указывать параметры типа при вызове полиморфных методов или обобщенных классов. Компилятор Scala определит тип параметра из контекста и из типов фактически передаваемых параметров метода/конструктора.

Вот два примера:

case class MyPair[A, B](x: A, y: B)
val p = MyPair(1, "scala") // тип: MyPair[Int, String]

def id[T](x: T) = x
val q = id(1)              // тип: Int

Компилятор использует типы аргументов MyPair для определения типа A и B. Тоже самое для типа x.

Параметры

Для параметров компилятор никогда не выводит тип. Однако, в некоторых случаях, он может вывести типы для параметров анонимной функции при передаче ее в качестве аргумента.

Seq(1, 3, 4).map(x => x * 2)  // List(2, 6, 8)

Параметр у map - f: A => B (функциональный параметр переводящий тип из A в B). Поскольку мы разместили целые числа в нашей последовательности Seq, компилятор знает, что элемент A является Int (т.е. x является целым числом). Поэтому компилятор может определить из выражения x * 2, что результат (B) является типом Int.

Когда не следует полагаться на выведение типа

Обычно считается, наиболее удобочитаемым объявить тип членов, которые открыты для публичного использования через API. Поэтому мы рекомендуем вам явно указывать тип для любых API, которые будут доступны пользователям вашего кода.

Кроме того, выведение может иногда приводить к слишком специфичному типу. Предположим, мы напишем:

var obj = null

Тогда мы не сможем далее сделать это переназначение:

obj = new AnyRef

Такое не будет компилироваться, потому что для obj предполагался тип Null. Поскольку единственным значением этого типа является null, то невозможно присвоить другое значение.

Contributors to this page: