2016-04-15 3 views
3

Ich versuche zu ändern, um die folgendenWie parametrischer Art während der Instanziierung in Julia

type Foo{T} 
    x::changeType(T) 
end 

, wo die Funktion changeType ändert den Typ-Parameter auf eine andere Art zu tun. Es muss keine Funktion sein, ich bin glücklich mit einem Wörterbuch oder einem Makro oder w/e, ich brauche nur einen Weg, dies zu tun.

Ich habe es mit einer Funktion und einem Wörterbuch probiert und beides führte zu Fehlern.

Antwort

3

Ich glaube, das ist nicht ganz möglich. Sie können jedoch mit einigen Problemumgehungen spielen.

  1. die Art der x nicht beschränken Sie und instanziiert nur x mit der richtigen Art manualy:

    erstellen
    const types = Dict(Int64 => Float32) 
    
    type Foo{T} 
        x::T 
    end 
    
    foo(k) = Foo{get(types, T, T)} 
    

    Dann:

    type Foo{T} 
        x 
        y::T 
    end 
    
    >>> f = Foo{Int32}(5.0f0, 2) 
    Foo{Int32}(5.0f0,2) 
    >>> typeof(f.x), typeof(f.y) 
    (Float32, Int32) 
    
  2. Sie Ihr Objekt in einer Funktion wrap ein Objekt von Foo

    >>> foo(Int64) 
    Foo{Float32} 
    
  3. Wenn Sie gemischte Felder in derselben type (z. B. Felder T und map(T)) Sie ein wenig den Konstruktor ändern können:

    const types = Dict(Int64 => Float32) 
    
    type Foo{T} 
        x 
        y::T 
    
        Foo(x=0, y=0) = new(get(types, T, T)(x), y) 
    end 
    

    Dies ermöglicht es Ihnen Foo als Foo{Int64} während Mapping x-Float32 zu erstellen:

    >>> Foo{Int64}(5, 2) 
    Foo{Int64}(5.0f0, 2)  # x is Float32, y is Int64 
    
  4. Und der letzte und wahrscheinlich Am sinnvollsten: Definieren Sie zunächst das Wörterbuch und verpacken Sie Ihre type in beide types:

    const types = Dict(Int64 => Float32) 
    
    type Foo{T, V} 
        x::V 
        y::T 
    end 
    

    Nun wickeln die Konstruktion eines Foo Objekt in eine Funktion:

    foo(T) = Foo{T, get(types, T, T)} 
    foo(T, args...) = Foo{T, get(types, T, T)}(args...) 
    

    foo Funktionsobjekte vom Typ erzeugt Foo wobei der erste Parameter V den Typ T von Foo und die Art angibt, wird dynamisch von der types gefolgert Wörterbuch.

    >>> foo(Int64) 
    Foo{Int64,Float32} 
    >>> foo(Int64, 5, 2) 
    Foo{Int64,Float32}(5.0f0,2) # x is Float32, y is Int64 
    

Hinweis: in den beiden oben genannten Methoden, wenn T nicht im types Wörterbuch definiert ist, gibt die Funktion getT und somit x-T abgebildet. Ist eine Fallback-Methode für Typen, die keine Zuordnung erfordern. Z.B.für die dritte Option:

>>> Foo{Int32}(5, 2) 
Foo{Int32}(5,2) 

beide x und y sind Int32 seit Int32 nicht in der Mapping-dict types ist. Und für die vierte Option:

>>> foo(Int32) 
Foo{Int32,Int32} 

Ich glaube, zur Zeit die Art der x kann nicht bei der Kompilierung als Funktion der T angegeben werden, aber die oben genannten Abhilfen sollten die Arbeit machen.

Ich weiß auch nicht, wie schlau ist der Julia-Compiler .. vorausgesetzt, dass das types Wörterbuch ist konstant, könnte es einige kluge Dinge tun und den Typ von x von dort abzuleiten (vielleicht könnte ein Entwickler dies beantworten oder weiter geben Verbesserungen).

+2

'const types = Dict (...)' macht das Wörterbuch nicht unveränderlich - es bedeutet nur, dass die Bindung 'types' immer auf dieses Wörterbuch verweist. Also kann Julia keine Kompilierungszeit über solche Typumwandlungen ableiten. Wenn Sie diesen Typ stabil machen möchten, können Sie stattdessen den Methodenversand verwenden: 'change_type {T} (:: Type {T}) = T; change_type (:: Typ {Int64}) = Float64'. –

+0

@MattB. Wow danke für die Klarstellung. Ich nahm an, dass "const" das Diktat unveränderlich machen würde, aber versuchte es in einem Terminal und wie du gesagt hast, erlaubt es mir, neue Gegenstände hinzuzufügen. Der 'change_type', den Sie erwähnen, ist wahrscheinlich die beste Option, um das Wörterbuch zu ersetzen :) –

Verwandte Themen