Джулия: Аргументы функций - Типовая спецификация массивов - PullRequest
2 голосов
/ 25 сентября 2019

Похоже, я что-то упустил из-за множественных диспетчерских + параметрических типов:

Целое число - абстрактный супертип всех целочисленных типов, поэтому метод f(arg::Integer) работает, как и ожидалось:

f(arg::Integer) = println("an integer")
# f(42) prints "an integer"
# f(UInt8(42)) prints "an integer"

Но если вы попробуете то же самое с одномерным массивом целых чисел в качестве типа аргумента, Джулия ответит сообщением об ошибке:

f(arg::Array{Integer, 1}) = println("an array with integers")
f(arg::Array{Signed, 1}) = println("an array with signed integers")
# f([1,2,3]) gives "no method matching f(::Array{Int64,1})..."

Есть идеи, что здесь не так?- Заранее спасибо!

1 Ответ

4 голосов
/ 25 сентября 2019

Вы сталкиваетесь с параметрической инвариантностью типов, это приятное оранжевое окно предупреждения в руководстве здесь .

Ссылаясь на соответствующую часть:

Конкретные типы точек с разными значениями T никогда не являются подтипами друг друга:

julia> Point{Float64} <: Point{Int64}
false

julia> Point{Float64} <: Point{Real}
false

Предупреждение

Этот последний пункт очень важен: даже если Float64 <: RealУ нас нет точки {Float64} <: Point {Real}. </p>

Для вашего примера вам потребуется:

f(arg::Array{<:Integer, 1}) = println("an array with integers")
# Alternatively f(arg::Array{T, 1}) where T <: Integer = println("an array with integers")
f(arg::Array{Signed, 1}) = println("an array with signed integers")

Первый метод - это запасной вариант.для общих целочисленных массивов, второй может быть вызван с определенным типом Array{Signed, 1}:

julia> f([1,2,3])
an array with integers

julia> f(Array{UInt8, 1}([1,2,3]))
an array with integers

julia> f(Array{Signed, 1}([1,2,3]))
an array with signed integers
...