Что это означает в сигнатурах функций, например:
convert(::Type{T}, z::Complex) where {T<:Real}
<:( Т1, Т2)
Оператор подтипа: возвращает true
тогда и только тогда, когда все значения типа T1
равны
также типа T2
.
Примеры:
Float64 <: AbstractFloat
=> true
Vector{Int} <: AbstractArray
=> true
Matrix{Float64} <: Matrix{AbstractFloat}
=> false
Строго говоря, следует различать предикат Base.:(<:)
, как описано в ответе @Saqib, и синтаксическое использование <:
для описания ограничений.
Это синтаксическое использование может иметь место в объявлениях параметров типа методов, чтобы ограничить переменную типа подтипом другого типа:
f(x::T) where {T<:Real} = zero(x)
Своеобразный особый случай этого - когда вы ограничиваете параметр типа структуры (struct Foo{T<:Real} ... end
), который ограничивает методы сгенерированного конструктора и позволяет применять конструктор типа только к ограниченным подтипам.
С другой стороны, помимо параметров типа, <:
можно использовать для объявления нового типа как подтипа другого (обязательно абстрактного) типа:
struct Foo <: Real end
Хотя оба случая соответствуют значению предиката подтипа, вы не можете заменить их другими произвольными выражениями (например, вы не можете записать ... where {isreal(T)}
в f
).
См. Мой комментарий по другому вопросу, я ошибся и испортил свой тестовый пример.
Хотя это все-таки как-то особый случай. Я думаю, мы могли бы думать о семантике как об определении метода Core.apply_type(::Type{Foo}, ::Type{T}) where {T<:Real})
(если бы он не был встроенным).
На самом деле, если я набираю
struct Foo{T<:Real} end; Foo{String}
в REPL, я получаюTypeError: in Foo, in T, expected T<:Real, got Type{String}
, что указывает мне, что это не просто ограничение для конструкторов (в Julia версии 1.5). Может быть,Foo{String}
работал раньше, но теперь они исправили это поведение?