2015-07-14 9 views
6

Wie bekomme ich den Subtyp einer Instanz eines parametrischen Typs in Julia? Zum Beispiel:Wie extrahiert man den spezifischen Typ aus einer Instanz eines generischen Typs in Julia?

immutable Dog{T <: Number} 
    snout::T 
end 

dog = Dog(5.) 
typeof(dog) 

... gibt Dog{Float64} zurück. Gibt es eine Möglichkeit, vom Typ aus der Variablen dog ohne explizite Bezugnahme auf das Feld snout zu kommen?

+0

Ich bin nicht sicher, dass Sie das Wort „abstrakt“ hier verwenden bedeuten zu. Ein abstrakter Typ ist nur ein Knoten in der Typhierarchie und wird mit 'abstract MyAbstractType' definiert. Ihr Typ 'Hund' scheint parametrisch, unveränderlich und zusammengesetzt zu sein, aber * nicht * abstrakt. –

+1

Ich glaube auch, dass du am ehesten "Feldtyp (Hund, 1)" oder "Feldtyp (Hund,: Schnauze)" findest. Ich kenne keine Methode, um den Typparameter einer Instanz eines parametrischen Typs zurückzugeben (obwohl es möglich ist, dass ein undokumentierter Typ existiert). –

+0

Danke, ich habe das Wort "Abstrakt" durch "parametrisch" ersetzt. – user3271788

Antwort

1

Nein, weil die Art der dogDog{Float64} ist nichtFloat64. Stellen Sie sich vor, welche Ausgabe erwartet wird, wenn Sie Dog durch mehr als einen Typ parametrisieren.

Der empfohlene Weg ist, ein Verfahren zu verwenden, um eine Art/unveränderlichen Felder zuzugreifen:

julia> type Foo{T <: Number, S <: AbstractString} 
      bar::T 
      baz::S 
     end 

julia> foo = Foo(5.5, "test") 
Foo{Float64,ASCIIString}(5.5,"test") 

julia> typeof(foo) 
Foo{Float64,ASCIIString} 

julia> typeof(foo.bar) 
Float64 

julia> typeof(foo.baz) 
ASCIIString 

julia> for field in names(Foo) 
      @eval $(field)(x::Foo) = x.$field 
     end 

julia> typeof(bar(foo)) 
Float64 

julia> typeof(baz(foo)) 
ASCIIString 
+0

Ja, das verstehe ich - meine Frage im Zusammenhang mit Ihrer Antwort ist, ob es eine Möglichkeit gibt, die Typen von Bar und Baz zu extrahieren, ohne sie namentlich zu nennen. – user3271788

+0

user3271788, ich denke Toivo Henningssons Antwort ist die richtige für dich, Tom Breloffs Antwort tut was du willst aber sieht hacky aus (alles um nicht auf einen Bezeichner zu verweisen?). Was ist dein Anwendungsfall? Könnten Sie Ihre Frage mit einem Beispiel für eine Sprache erweitern, in der Sie dies tun können und warum dies nützlich ist? – SalchiPapa

9

Es auf Ihren Anwendungsfall abhängt. Wenn Sie in einem konkreten Fall so interessiert sind, ist ein guter Weg, um eine Funktion

dogtype{T}(::Dog{T}) = T 

Dann wird dogtype(Dog(.5)) Sie Float 64 geben zu definieren.

Dies ist die Art von Muster, das verwendet wird, um die eltype-Funktion in Base Julia zu implementieren.

2

Dies funktioniert für mich:

julia> VERSION 
v"0.4.0-dev+5733" 

julia> immutable Dog{T <: Number} 
      snout::T 
     end 

julia> dog = Dog(0.5) 
Dog{Float64}(0.5) 

julia> typeof(dog).parameters[1] 
Float64