私は次のことをしようとしています
type Foo{T}
x::changeType(T)
end
関数changeType
は型パラメーターを他の型に変更します。関数である必要はありません。辞書やマクロを使用したり、これを行う方法が必要なだけです。
関数と辞書の両方で試してみましたが、どちらもエラーになりました。
私は次のことをしようとしています
type Foo{T}
x::changeType(T)
end
関数changeType
は型パラメーターを他の型に変更します。関数である必要はありません。辞書やマクロを使用したり、これを行う方法が必要なだけです。
関数と辞書の両方で試してみましたが、どちらもエラーになりました。
これは完全には不可能だと思います。ただし、いくつかの回避策で遊ぶことができます。
の型を制約せず、手動で適切な型x
でインスタンス化するだけです。x
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)
オブジェクトを関数でラップできます。
const types = Dict(Int64 => Float32)
type Foo{T}
x::T
end
foo(k) = Foo{get(types, T, T)}
次に、のオブジェクトを作成しますFoo
>>> foo(Int64)
Foo{Float32}
同じタイプのフィールドを混在させたい場合type
(例:T
とのフィールドmap(T)
)、コンストラクターを少し変更できます。
const types = Dict(Int64 => Float32)
type Foo{T}
x
y::T
Foo(x=0, y=0) = new(get(types, T, T)(x), y)
end
これにより、次のようにマッピングしながらFoo
asを作成できます。Foo{Int64}
x
Float32
>>> Foo{Int64}(5, 2)
Foo{Int64}(5.0f0, 2) # x is Float32, y is Int64
そして最後で、おそらく最も実行可能なもの: 最初に辞書を定義しtype
、両方でラップしますtypes
:
const types = Dict(Int64 => Float32)
type Foo{T, V}
x::V
y::T
end
Foo
オブジェクトの構築を関数にラップします。
foo(T) = Foo{T, get(types, T, T)}
foo(T, args...) = Foo{T, get(types, T, T)}(args...)
foo
Foo
関数は、最初のパラメーターが型を指定する型T
のオブジェクトを作成Foo
し、その型は辞書V
から動的に推測されます。types
>>> foo(Int64)
Foo{Int64,Float32}
>>> foo(Int64, 5, 2)
Foo{Int64,Float32}(5.0f0,2) # x is Float32, y is Int64
注: 上記の両方のメソッドで、が辞書でT
定義されていない場合、関数は戻り、したがってにマップされます。マッピングを必要としない型のフォールバック メソッドです。たとえば、3 番目のオプションの場合:types
get
T
x
T
>>> Foo{Int32}(5, 2)
Foo{Int32}(5,2)
x
との両方y
は、マッピング dict に含まれていないInt32
ためです。4 番目のオプションの場合:Int32
types
>>> foo(Int32)
Foo{Int32,Int32}
x
現在、 の型をの関数としてコンパイル時に指定することはできないと思いますT
が、上記の回避策でうまくいくはずです。
Juliaコンパイラがどれほどスマートかはわかりません..types
辞書が一定であることを考えると、いくつかのスマートなことを行い、そこから型を推測する可能性がありますx
(開発者はこれに答えるか、さらに改善することができます)。