Разница между сопоставлением String и Int в Scala

Рассмотрим следующие два фрагмента кода:

scala> def f1(x:Any) = x match { case i:String => i; case _ => null }
f1: (x: Any)String

scala> def f2(x:Any) = x match { case i:Int => i; case _ => null }
f2: (x: Any)Any

Почему f2 возвращает тип Any, а f1 - String? Я ожидал, что либо оба вернут Any, либо f2 вернут Int.


person Jus12    schedule 28.02.2011    source источник


Ответы (1)


Вывод типа выбирает наименьший общий супертип, если метод возвращает разные типы.

Ваша функция f1 возвращает String или null, общим супертипом которого является String, поскольку String может иметь значение null. Строка является подклассом AnyRef, а AnyRef может иметь значения null.

Ваша функция f2 возвращает Int (подкласс AnyVal) или null, общим супертипом которого является Any. Int не может быть null.

См. http://docs.scala-lang.org/tutorials/tour/unified-types.html для иерархии классов Scala.

Другой пример:

scala> def f3(b: Boolean) = if (b) 42
f: (b: Boolean)AnyVal

f3 возвращается

либо 42 это b это true

or () if b is false.

Таким образом, он возвращает типы Int и Unit. Общий супертип — AnyVal.

person michael.kebe    schedule 28.02.2011
comment
Есть ли какая-то причина не позволять Int быть null? Я думаю, было бы удобнее, если бы null также был членом AnyVal (или если бы Int и другие примитивные типы были экземплярами Anyref. - person Jus12; 28.02.2011
comment
Я думаю, это потому, что компилятор Scala использует примитивный тип данных (int, double, float,...) JVM для достижения наилучшей производительности. Но я точно знаю. Посмотрите на это: stackoverflow.com/questions/2335319/ - person michael.kebe; 28.02.2011
comment
@Jus12 Jus12 Классы AnyVal не являются ссылками, поэтому их нельзя аннулировать. - person Daniel C. Sobral; 01.03.2011