У меня есть функция, которая принимает 7 (ключевое слово) аргументов, каждый с указанным типом, а последний имеет значение по умолчанию, например:
function dummy(;truefalse1::S, somevar1::T, somevar2::T, somevar3::T, somevar4::T,
scalarvar::Int64, truefalse2::D = falses(3, 3)) where {
T <: Union{Array{Float64,2}, SubArray{Float64, 2}},
S <: AbstractArray{Bool}, D <: AbstractArray{Bool}}
###
end
Аргументы truefalse*
могут быть 2-мерные логические массивы (BitArray {2}) или их представление (например, view(somearray, 2:4, 3:5)
). Аргументы somevar*
могут быть либо двумерными массивами типа Float64, либо "view
" такого массива.
Вышеописанное работает, но эта, казалось бы, эквивалентная версия не работает (см. Ниже тестовый ввод):
function dummy(;truefalse1::S, somevar1::T, somevar2::T, somevar3::T, somevar4::T,
scalarvar::Int64, truefalse2::S = falses(3, 3)) where {
T <: Union{Array{Float64,2}, SubArray{Float64, 2}},
S <: AbstractArray{Bool}}
###
end
(Другими словами, тип D
был удален с использованием S
тип для обоих случаев.)
Сообщение об ошибке выглядит следующим образом:
ERROR: MethodError: no method matching #dummy#823(::SubArray{Bool,2,BitArray{2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}, ::SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}, ::SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}, ::SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}, ::SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false}, ::Int64, ::BitArray{2}, ::typeof(wheretonext))
Closest candidates are:
#dummy#823(::S, ::T, ::T, ::T, ::T, ::Int64, ::S, ::typeof(dummy)) where {T<:Union{Array{Float64,2}, SubArray{Float64,2,P,I,L} where L where I where P}, S<:(AbstractArray{Bool,N} where N)} at /SomePath/someDummyCode.jl:238
Stacktrace:
[1] (::var"#kw##dummy")(::NamedTuple{(:truefalse1, :somevar1, :somevar2, :somevar3, :somevar4, :scalarvar),Tuple{SubArray{Bool,2,BitArray{2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},UnitRange{Int64}},false},Int64}}, ::typeof(dummy)) at ./none:0
[2] top-level scope at none:0
Вот пример набора тестовых входных данных:
julia> using Random; Random.seed!(1234);
julia> trf1 = rand(5, 10) .> rand(5, 10); trf2 = rand(5, 10) .> rand(5, 10);
julia> smv1 = rand(5, 10); smv2 = rand(5, 10); smv3 = rand(5, 10); smv4 = rand(5, 10);
Эти Случаи вызывают вышеупомянутую ошибку, используя второе объявление функции:
julia> dummy(truefalse1 = view(trf1, 2:4, 3:5), somevar1 = view(smv1, 2:4, 3:5),
somevar2 = view(smv2, 2:4, 3:5), somevar3 = view(smv3, 2:4, 3:5),
somevar4 = view(smv4, 2:4, 3:5), scalarvar = 1)
julia> dummy(truefalse1 = view(trf1, 2:4, 3:5), somevar1 = view(smv1, 2:4, 3:5),
somevar2 = view(smv2, 2:4, 3:5), somevar3 = view(smv3, 2:4, 3:5),
somevar4 = view(smv4, 2:4, 3:5), scalarvar = 1, truefalse2 = falses(3, 3))
Однако, все еще используя второе объявление функции, этот случай работает нормально:
julia> dummy(truefalse1 = view(trf1, 2:4, 3:5), somevar1 = view(smv1, 2:4, 3:5),
somevar2 = view(smv2, 2:4, 3:5), somevar3 = view(smv3, 2:4, 3:5),
somevar4 = view(smv4, 2:4, 3:5), scalarvar = 1, truefalse2 = view(trf2, 2:4, 3:5))
(Напомним: Все Приведенные выше тестовые примеры прекрасно работают с первым объявлением функции.)
Буду очень признателен за любые предположения о том, что я мог сделать неправильно или какие могут быть соответствующие тонкости в языке Julia. Это моя вторая неделя кодирования в Юлии, поэтому я также приветствую любые другие советы. Спасибо!