Вы получаете это MethodError
, потому что Tuple{Vararg{T}}
не является конкретным типом, так как число элементов для Vararg
не определено, а Параметры типа Юлии инвариантны , а не ковариант .
Несмотря на то, что у нас есть Tuple{Vararg{String, 5}} <: Tuple{Vararg{String}}
, у нас нет Vector{Tuple{Vararg{String, 5}}} <: Vector{Tuple{Vararg{String}}}
julia> Tuple{Vararg{String, 5}} <: Tuple{Vararg{String}}
true
julia> Vector{Tuple{Vararg{String, 5}}} <: Vector{Tuple{Vararg{String}}}
false
Вместо этого вы должны использовать следующие подписи, чтобы избавиться отошибка
function f(a::Vector{<:Tuple{Vararg{String}}})
# or
function f(a::Vector{T}) where {T <: Tuple{Vararg{String}}
в соответствии с предложениями @crstnbr и @ BogumiłKamiński.Эти сигнатуры избавят от ошибки, однако они не ограничивают кортежи одинаковой длины.Например, вы можете вызывать эти функции с помощью
f([("x1, x2"), ("y1", "y2", "y3"])
Поскольку вы хотите, чтобы кортежи в массиве содержали одинаковое количество элементов, вам нужно указать это ограничение в аннотации типа.Документация для Vararg
содержит информацию о том, как указать количество элементов.
Vararg{T,N}
Последний параметр типа кортежа Tuple может быть специальным типом Vararg., который обозначает любое количество конечных элементов.Тип Vararg{T,N}
соответствует в точности N
элементам типа T
.Vararg{T}
соответствует нулю или более элементам типа T
.Vararg
типы кортежей используются для представления аргументов, принимаемых методами varargs (см. Раздел «Функции Varargs» в руководстве.)
Вы можете использовать
function f(a::Vector{Tuple{Vararg{String, N}}}) where N
...
end
илииспользуя компактный способ NTuple
вместо
function f(a::Vector{NTuple{N, String}}) where N
end
Эти подписи будут обеспечивать ограничения, которые вы хотели в вопросе.
Примечания
Возможно, вы чрезмерно специализируете свои типы .
Как заметил @ Bogumił Kamiński в разделе комментариев, лучше работать с типом AbstractString
вместо конкретного типа String
.
function f(a::Vector{<:NTuple{N, AbstractString}}) where N
...
end
Вы также можете рассмотреть возможность работы с AbstractVector
вместо Vector
.