3

我正在尝试执行以下操作

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

其中函数changeType将类型参数更改为其他类型。它不一定是一个函数,我很高兴使用字典或宏或 w/e,我只需要一种方法来做到这一点。

我用函数和字典都试过了,都导致了错误。

4

1 回答 1

3

我相信这不是完全可能的。但是,您可以尝试几种解决方法。

  1. 不要限制类型,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)
    
  2. 您可以将对象包装在一个函数中:

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

    然后创建一个对象Foo

    >>> foo(Int64)
    Foo{Float32}
    
  3. 如果你想在相同的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
    

    这将允许您创建Fooas Foo{Int64}while 映射xFloat32

    >>> Foo{Int64}(5, 2)
    Foo{Int64}(5.0f0, 2)     # x is Float32, y is Int64
    
  4. 最后一个,也可能是最可行的一个:首先定义字典并将你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其中第一个参数指定类型TFoo并且类型是从字典V中动态推断的。types

    >>> 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)

bothxyareInt32因为Int32不在映射 dicttypes中。对于第四个选项:

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

我认为目前x无法在编译时将类型指定为 的函数T,但上述解决方法应该可以完成这项工作。

我也不知道 Julia 编译器有多聪明。鉴于types字典是常量,它可能会做一些聪明的事情并x从那里推断出类型(也许开发人员可以回答这个问题或提供进一步的改进)。

于 2016-04-15T09:30:12.820 回答