3 votes

Tableaux numériques génériques dans Julia

J'essaie d'apprendre Julia en lisant la documentation, et ils ont un code qui ressemble à ceci :

function testFunction(x::Number)
    return x+5
end

Il s'agit d'une fonction qui fonctionne pour n'importe lequel des nombreux types numériques de Juila.

Cependant, si j'essaie de faire quelque chose de similaire, comme ceci :

function testFunction2(x::Array{Number})
    return x
end

Je reçois l'erreur suivante :

ERROR: MethodError: no method matching testFunction2(::Array{Int64,1})
Closest candidates are:
  testFunction2(::Array{Number,N} where N) at /Users/.../Desktop/Test.jl:45

Est-ce que je fais quelque chose de mal ? J'ai pensé à ça : Array{Float64} permet de déclarer un tableau d'un type spécifique, mais l'utilisation d'un type tel que Number qui fonctionne dans le cas normal, ne fonctionne pas ici... Tout commentaire est apprécié.

8voto

sujeet Points 265

La définition

function testFunction2(x::Array{Number})
    return x
end

est la fonction d'identification qui accepte en entrée un Array{Number} . Ainsi, ce qui suit fonctionnera :

testFunction2(collect((1,3,-2.7,5+2im)))

mais cela va no travail :

testFunction2([1,3,7,9])

On peut le voir d'ici :

julia> typeof(collect((1,3,-2.7,5+2im)))
Array{Number,1}

julia> typeof([1,3,7,9])
Array{Int64,1}

Le premier correspond au type de x dans votre définition de testFunction2 et le second ne le fait pas. (Notez que Array{Number} est synonyme de Array{Number,1} .)

Ce que vous recherchez est une fonction qui accepte un tableau de tout type d'élément qui est un sous-type de Number . Cela se fait comme :

function testFunction2(x::Array{T}) where {T<:Number}
    return x
end

où nous avons maintenant un paramètre T qui peut être n'importe quel sous-type de Number . Vous pouvez aussi utiliser le sucre

function testFunction2(x::Array{<:Number})
    return x
end

ou même testFunction2(x::Array{<:Number}) = x .

5voto

sundar Points 2271

En complément de l'autre réponse : la raison pour laquelle il y a une différence de comportement entre l'exemple dans le manuel et votre code est que dans votre cas, Number est utilisé comme paramètre de type dans un autre type ( Array ). Les contrôles de type sont plus stricts que si Number a été utilisé comme type par lui-même. Comme le dit @StefanKarpinski dans cette réponse ,

C'est une conséquence de l'invariance de type paramétrique dans Julia. Voir le chapitre sur les types dans le manuel pour plus de détails.

(Lien corrigé pour être actuel.)

Le point clé du manuel est le suivant : "même si Float64 < : Real, nous n'avons PAS Point{Float64} < : Point{Real}." De même dans votre cas, même si nous avons Int64 <: Number nous ne pas ont Array{Int64} <: Array{Number} C'est pourquoi la correspondance des types échoue.

Donc en général, vous peut écrire x::Number pour correspondre à n'importe quel type de numéro, vous pouvez écrire p::AbstractString pour correspondre à tout type de chaîne de caractères qui est un sous-type de AbstractString etc. Mais si vous utilisez le type abstrait comme paramètre de type dans le cadre d'un autre type, vous devez spécifier explicitement que vous voulez qu'il corresponde à tous les sous-types du type de paramètre, c'est-à-dire avec Point{<:Real} o Array{<:Number} .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X