Я новичок в Юлии.
Мне было любопытно узнать тип значения в julia, поэтому я тестирую их несколько.
using StaticArrays
struct MT{N,Np1}
x::SVector{N,Int}
y::SVector{Np1,Int}
function MT(x::SVector{T,Int},y::SVector{V,Int}) where {T, V}
Val{T}() == Val{V}() || throw(ArgumentError("mismatched lengths; y must be one element longer than x"))
new{T, V}(x,y)
end
end
MT(SVector{3,Int}(1,2,3),SVector{3,Int}(1,2,3))
Мой вопрос таков:
Мне нужен рабочий код с аннотацией типа.
struct MT{N,Np1}
x::SVector{N,Int}
y::SVector{Np1,Int}
function MT(x::SVector{T,Int},y::SVector{V,Int}) where T <: Integer where V <: Int
Val{T}() == Val{V}() || throw(ArgumentError("mismatched lengths; y must be one element longer than x"))
new{T, V}(x,y)
end
end
делает то, что вы просите (он просто заменяет where {T, V}
в вашем коде на where T <: Integer where V <: Int
. См. документацию для where
для получения дополнительной информации.
Есть несколько вопросов, которые я рассмотрел по поводу вашего вопроса. SVector{S, T} может иметь тип T, различающийся по типу, но S является числом элементов и, насколько мне известно, должен быть Int. Таким образом, пакет SVector должен обеспечить для вас тип S. Таким образом, where
обычно используется для изменения второго типа в SVector, который вы всегда устанавливаете здесь как Int.
Этот ответ не подойдет, так как 3
не является подтипом Integer
. Отношение между 3
и Integer
является isa
-отношением, а не <:
-отношением.
Я думаю, что, поскольку where() требует типов в качестве аргументов, и ваша проблема заключается в том, что вы хотите воздействовать на значение целого числа, а не на целое число, я бы не стал использовать свой ответ, а вместо этого использовал что-то вроде if Val(V) - T != 1
в тело функции и вообще не указывать T с where
.
Ответ на ваш вопрос об ограничении типа параметров T
и V
заключается в том, что вы не можете сделать это для параметров, отличных от типа/значения. Было бы неплохо, но нельзя.
Только отношения подтипа могут быть применены к параметрам типа, а параметры-значения не могут быть в отношениях подтипа:
julia> 3 isa Integer # this is a valid relationship
true
julia> 3 <: Integer # this is not
ERROR: TypeError: in <:, expected Type, got a value of type Int64
Вместо этого гипотетический синтаксис может быть where {T::Int, V::Int}
или where {T isa Int, V isa Int}
. Я не знаю, почему это невозможно, но это общеизвестное ограничение.
Кстати: вы можете просто написать T == V
. Не надо Val{T}() == Val{V}()
. Вычисление происходит во время компиляции, так как оба являются параметрами типа.
После вашего определения MT выполнение «MT (SVector {3, Int} (1,2, 3), SVector {3, Int} (1, 2, 3))» дает мне ошибку (тем не менее, код, который я написал, работающий). Мои фокусы были на T и V. Я думал, что T и V просто работают, как концепция, называемая const generic в ржавчине, поэтому она будет иметь аннотацию типа. (например: ограничить тип T как Integer). Является ли S в SVector {S, T} просто числом, а не типом, поэтому оно находится в общем параметре?