Ваш шаблон кортежа case (_, _)
- это просто шаблон конструктора case Tuple2(_, _)
.
Шаблон конструктора с параметрами типа выводится как case _: Tuple2[x, y]
.
Ваша переменная будет иметь тип, который выведен, и вы спрашиваете, почему x
и y
выводят, как они есть.
В раздел о выводе втипизированные шаблоны , он обещает использовать самые слабые ограничения, которые подразумевают соответствие ожидаемому типу.
В этом случае самые слабые ограничения: <: Int
и <: AB
.
Вкл.с другой стороны, чтобы прояснить тип связанных переменных для сопоставления с образцом, таких как
(Vector.empty: Seq[Nothing]) match { case x @ Nil => x }
, который является не проверкой типа, а проверкой на равенство, и генерирует 2.12, но не 2.13, спецификация теперь говорит :
Тип переменной x - это статический тип T, подразумеваемый шаблоном p.Шаблон p подразумевает тип T, если шаблон соответствует только значениям типа T.
Этот язык может предполагать, что ваша интуиция верна, поскольку, очевидно, (_, A(_))
соответствует толькозначения типа (_, A)
.Это, кажется, подтверждается определением :
Шаблон соответствует всем объектам, созданным из вызовов конструктора c (v1,…, vn), где каждый шаблон элемента pi соответствует соответствующему значениюvi.
Однако то, что шаблон подразумевает тип, не означает, что тип связанной переменной является самым узким типом, подразумеваемым шаблоном.Что это могло бы означать для Nil
примера?
К сожалению, первая форма - - еще не допустимый синтаксис :
case x @ Tuple2[Int @unchecked, A @unchecked](_, A(_)) => x
case x @ Tuple2(_, A(_)) => x.asInstanceOf[(Int, A)]