Ответ 1
3.5.3 Слабое соответствие В некоторых ситуациях Scala используется более общий соответствие отношение. Тип S слабо соответствует типу T, записанному S <: w T, если S <: T или оба S и T являются примитивные типы номеров и S предшествуют T в следующем порядке.
- Byte <: w Short
- Байт <: w Символ
- Short <: w Int
- Int <: w Long
- Long <: w Float
- Float <: w Двойной
Слабая наименьшая верхняя грань является наименьшая верхняя граница относительно слабого соответствие.
Где это используется? Во-первых, он определяет тип выражений if
:
Тип условного выражения - слабая наименьшая верхняя граница (п. 3.5.3) типов e2 и e3
В Scala 2.7.x это будет по типу AnyVal
, наименьшая верхняя граница Int
и Double
. В 2.8.x он имеет вид Double
.
scala> if (true) 1 else 1d
res0: Double = 1.0
Аналогично:
scala> try { 1 } catch { case _ => 1.0 }
res2: Double = 1.0
scala> (new {}: Any) match { case 1 => 1; case _ => 1.0 }
res6: Double = 1.0
scala> def pf[R](pf: PartialFunction[Any, R]): PartialFunction[Any, R] = pf
pf: [R](pf: PartialFunction[Any,R])PartialFunction[Any,R]
scala> pf { case 1 => 1; case _ => 1d }
res4: PartialFunction[Any,Double] = <function1>
Другое место, которое оно используется, относится к типу вывода:
scala> def foo[A](a1: A, a2: A): A = a1
foo: [A](a1: A,a2: A)A
scala> foo(1, 1d)
res8: Double = 1.0
scala> def foos[A](as: A*): A = as.head
foos: [A](as: A*)A
scala> foos(1, 1d)
res9: Double = 1.0
А также для простого числового расширения:
Числовое расширение. Если e имеет примитив тип номера, который слабо соответствует (П. 3.5.3) к ожидаемому типу, расширенный до ожидаемого типа с использованием одного из 6.26 Неявные преобразования 97 числовых методов преобразования toShort, toChar, toInt, toLong, toFloat, toDouble определенной в п. 12.2.1. ожидаемый тип примитивный числовой тип Byte, Short или Char, а выражение e является целочисленный литеральный монтаж в диапазоне этого типа, он преобразуется в такой же литерал в этом типе.
scala> 1: Double
res10: Double = 1.0
UPDATE
Как отметил Даниэль, спецификация ошибочна в отношении того, какие типы имеют слабую совместимость. Позвольте спросить самого компилятора:
scala> :power
** Power User mode enabled - BEEP BOOP **
** scala.tools.nsc._ has been imported **
** New vals! Try repl, global, power **
** New cmds! :help to discover them **
** New defs! Type power.<tab> to reveal **
scala> settings.maxPrintString = 10000
scala> import global.definitions._
import global.definitions._
scala> (for{c1 <- ScalaValueClasses;
c2 <- ScalaValueClasses
isNSC = isNumericSubClass(c1, c2)
if isNSC
} yield ("isNumericSubClass (%s, %s) = %b" format (c1, c2, isNSC))).mkString("\n")
res5: String =
isNumericSubClass (class Byte, class Byte) = true
isNumericSubClass (class Byte, class Short) = true
isNumericSubClass (class Byte, class Int) = true
isNumericSubClass (class Byte, class Long) = true
isNumericSubClass (class Byte, class Float) = true
isNumericSubClass (class Byte, class Double) = true
isNumericSubClass (class Short, class Short) = true
isNumericSubClass (class Short, class Int) = true
isNumericSubClass (class Short, class Long) = true
isNumericSubClass (class Short, class Float) = true
isNumericSubClass (class Short, class Double) = true
isNumericSubClass (class Int, class Int) = true
isNumericSubClass (class Int, class Long) = true
isNumericSubClass (class Int, class Float) = true
isNumericSubClass (class Int, class Double) = true
isNumericSubClass (class Long, class Long) = true
isNumericSubClass (class Long, class Float) = true
isNumericSubClass (class Long, class Double) = true
isNumericSubClass (class Char, class Int) = true
isNumericSubClass (class Char, class Long) = true
isNumericSubClass (class Char, class Char) = true
isNumericSubClass (class Char, class Float) = true
isNumericSubClass (class Char, class Double) = true
isNumericSubClass (class Float, class Float) = true
isNumericSubClass (class Float, class Double) = true
isNumericSubClass (class Double, class Double) = true