Определить и описать ограничения Scala общего типа
Я видел <:
, >:
<%
и т.д. Может ли кто-нибудь дать (или найти) хорошее описание этого? Каковы возможные ограничения, что они делают, и каков пример того, когда их использовать?
Ответы
Ответ 1
S <: T
означает, что S
является подтипом T
. Это также называется привязкой верхнего типа. Точно так же S >: T
означает, что S
является супертипом T
, нижнего ограничения типа.
S <% T
является границей вида и выражает, что S
должен иметь вид , который отображает его значения в значения типа T
.
Это сбивает меня с толку, и у меня есть магистры в языках программирования из Беркли.
Ответ 2
Здесь есть два разных зверя, но они все знают как "границы", а не "ограничения"...
Во-первых, это границы типов:
-
<:
- связанный с верхним типом
-
>:
- связанный ниже тип
Они по существу совпадают с super
и extends
в java и будут фактически закодированы как таковые в сгенерированном байт-коде, который хорош для interop:)
Затем идет синтаксический сахар:
-
<%
- просмотр связанного
-
:
- связанный контекст
Они НЕ кодируются способом, который Java может понять (хотя они представлены в подписи scala, аннотации, которые scala добавляет ко всем классам, чтобы помочь компилятору, и которая в конечном итоге будет основой библиотека отображения scala)
Оба они преобразуются в неявные параметры:
def fn[A <% B](arg: A) = ... //sugared
def fn[A](arg: A)(implicit ev: A => B) = ... //unsugared
def fn[A : Numeric](arg: A) = ... //sugared
def fn[A](arg: A)(implicit ev: Numeric[A]) = ... //unsugared
По этой причине вы не можете комбинировать свои собственные импликации с ограничениями на просмотр или границы контекста, поскольку scala разрешает только один блок, помеченный как неявный для любой функции или конструктора.
Если вам нужно использовать свои собственные импликации, вы должны сначала вручную преобразовать любые такие ограничения в unsugared версию и добавить это в неявный блок.