Gegeben ein Array von Arrays x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10]
, berichtet Julia seinen Typ als Array{Array{T,N},1}
. Dies täuscht, denn es scheint zu implizieren, dass es einige T
und einige N
gibt, für die der obige Typ passt. Aber das ist nicht der Fall: die ungeraden Elemente werden vom Typ Array{Int,1}
sein, und die Evens sind Array{Float64,2}
. Also, wenn Sie versuchen, eine Methode für foo
mit den Typparameter zu schreiben:
foo{T,N}(::Array{Array{T,N},1}) = T,N
Was für x
sind T
und N
? Natürlich gibt es kein solches N - es ist sowohl 1 und 2! Und die Elemente dieser Subarrays sind nicht vom Typ Any
- sie sind sowohlInt
und Float64
. Dasselbe gilt für Array[[0,1],[0,1,2]]
, obwohl in Ihrem Beispiel Sie wissen, dass T
und N
konsistent sind, Julia's Typsystem nicht ... und Sie könnten möglicherweise Elemente, die keine Int-Vektoren sind, verschieben.
Es gibt eine Reihe von Möglichkeiten. Der beste Ansatz besteht darin, sicherzustellen, dass Ihre Arrays immer konkrete (oder zumindest einheitliche) Elementtypen haben, aber das ist nicht immer möglich. Wenn Sie Ihr Beispiel x
oben angeben, können Sie stattdessen schreiben: x = Array{Int,1}[[0,1],[1,2,3],[0,1,2,4]]
.
Eine weitere Alternative ist Ihre Funktion Signatur zu ändern:
foo{N}(x::Array{Array,N}) = 1 # Will *only* work for arrays like x above
foo{T<:Array, N}(x::Array{T,N} = 2 # Will work for all arrays of arrays
Die erste wird nur anwendbar, wenn Sie genau diese Art zu invariance aufgrund haben, während die zweite für alle Arrays von Arrays arbeiten, die beide schlecht getippt und Beton.
(Edit: Als abschließende Bemerkung, N<:Number
wird wörtliche Zahlen nicht übereinstimmen Es wird Typen übereinstimmen, ein Subtyp von Number
sind, wie Real
oder Int
..Es gibt derzeit keine Möglichkeit auszudrücken, dass ein Typparameter ein Wert vom Typ Int
sein muss, der über die Konvention hinausgeht, dass N eine ganze Zahl ist.
Können Sie ein Beispiel hinzufügen, wie Sie etwas wie Ihr 'x' erzeugen? Meine Ahnung ist, dass Sie auf [Invarianz] (http://docs.julaulang.org/en/release-0.3/manual/types/?highlight=invariant#parametric-composite-types) stoßen, und dass eine Definition wie 'foo {T <: Array} (x :: Array {T})' wird den Trick machen. –
Ja, das funktioniert, war ich nicht sicher über die Regeln für das Setzen des '' '{T <: Array}' '' Bit. Zum Beispiel, wenn ich mehr als ein Argument mit dem gleichen Problem hatte, wie kann ich hineinlegen mehrere Typparameter? Danke für den Link, es war sehr hilfreich, ich war mir nicht sicher, wo ich vorher hinschauen sollte. Ich habe ein Beispiel hinzugefügt, wie ich '' 'x''' zu der Frage erzeuge. – StephUnna