我正试图完成以下操作
type Foo{T}
x::changeType(T)
end
这里的函数changeType
是用来将类型参数更改为其他类型。它不一定非得是一个函数,也可以使用字典或宏等方式,只要能实现这个功能即可。
我尝试过使用函数和字典,但都出现了错误。
我正试图完成以下操作
type Foo{T}
x::changeType(T)
end
这里的函数changeType
是用来将类型参数更改为其他类型。它不一定非得是一个函数,也可以使用字典或宏等方式,只要能实现这个功能即可。
我尝试过使用函数和字典,但都出现了错误。
我相信这并不完全可能。但是,您可以尝试使用一些变通方法。
Do not constrain the type of x
and just instantiate x
with the proper type manualy:
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)
You can wrap your object in a function:
const types = Dict(Int64 => Float32)
type Foo{T}
x::T
end
foo(k) = Foo{get(types, T, T)}
Then create an object of Foo
>>> foo(Int64)
Foo{Float32}
If you want to have mixed type fields in the same type
(e.g. fields of T
and map(T)
) you can modify a bit the constructor:
const types = Dict(Int64 => Float32)
type Foo{T}
x
y::T
Foo(x=0, y=0) = new(get(types, T, T)(x), y)
end
This will allow you to create Foo
as Foo{Int64}
while mapping x
to Float32
:
>>> Foo{Int64}(5, 2)
Foo{Int64}(5.0f0, 2) # x is Float32, y is Int64
And the last, and probably the most viable one: first define the dictionary and wrap your type
in both types
:
const types = Dict(Int64 => Float32)
type Foo{T, V}
x::V
y::T
end
Now wrap the construction of a Foo
object into a function:
foo(T) = Foo{T, get(types, T, T)}
foo(T, args...) = Foo{T, get(types, T, T)}(args...)
foo
function creates objects of type Foo
where the first parameter specifies the type T
of Foo
and the type V
is dynamically inferred from the types
dictionary.
>>> foo(Int64)
Foo{Int64,Float32}
>>> foo(Int64, 5, 2)
Foo{Int64,Float32}(5.0f0,2) # x is Float32, y is Int64
T
没有在types
字典中定义,get
函数将返回T
,因此x
将被映射到T
。这是一种针对不需要映射的类型的后备方法。例如,对于第三个选项:>>> Foo{Int32}(5, 2)
Foo{Int32}(5,2)
由于Int32
不在映射字典types
中,因此x
和y
都是Int32
类型。至于第四个选项:
>>> foo(Int32)
Foo{Int32,Int32}
目前我认为无法在编译时将x
的类型作为T
函数的一部分进行指定,但上述解决方法应该能够解决问题。
我不知道Julia编译器有多聪明...鉴于types
字典是常量,它可能会从中推断出x
的类型(也许开发人员可以回答这个问题或提供更进一步的改进)。
const types = Dict(…)
并不会使字典变成不可变的,它只是意味着绑定types
将始终引用该字典。因此 Julia 无法对类型转换进行编译时推理。如果您想使其类型稳定,可以改用方法分派:change_type{T}(::Type{T}) = T; change_type(::Type{Int64}) = Float64
。 - mbaumanconst
会使字典不可变,但是在终端中尝试后,就像您所说的那样,它允许我添加新项。您提到的change_type
可能是替换字典的最佳选项 :) - Imanol Luengo