在Julia中创建非常相似的类型

时间:2016-05-19 20:47:25

标签: julia

假设我有两种类型,它们都是抽象类型的子类型

abstract A

type B <: A
x
y
z
end 

type C <: A
x
y
z
w
end

有没有办法创建C而无需基本上复制/粘贴B并添加额外的参数?主要问题是BC非常接近,我希望尽可能少的代码重复。我知道手册说混凝土类型不能互为子类型:

  

Julia的类型系统的一个特别显着特征是具体类型可能不会相互进行子类型化:所有具体类型都是最终类型,并且可能只有抽象类型作为其超类型。

有什么方法吗?

3 个答案:

答案 0 :(得分:9)

在这些情况下,我通常更喜欢撰写我的类型。

这是我的意思的一个例子:

abstract A

type B <: A
    x
    y
    z
end 

type C <: A
    b::B
    w
end

请注意C仍然是A的子类型,但包含B的实例作为字段。

更新

您确实无法再访问c.x,而是必须执行c.b.x。有一个简单的方法。

假设你有一个功能

function my_func(a::A)
    # do something with a.x, a.y, a.z
end

如果my_func适用于A的任何子类型,则它只能访问A所有子类型中通用的字段。在这种情况下,xyz

知道这一点,我还会定义一个特定版本的方法来调度C的实例,如下所示:

my_func(c::C) = my_func(c.b)

这有点冗长,但您可以轻松地将所有这些函数包含在使用@eval的元编程for循环中并一次生成所有这些函数。有关详细信息,请参阅docs

答案 1 :(得分:2)

我愿意

type XYZ
    x
    y
    z
end

type B <: A
    xyz::XYZ
end 

type C <: A
    xyz::XYZ
    w
end

当然,出于性能原因,我通常使用immutable以及注释尽可能多的类型。

答案 2 :(得分:1)

我用宏来做(如上面的评论中所述)。子类型保持分离,这通常比子子类型更自然:

abstract A
macro A_fields()
        quote
                a1
                a2
        end
end

type B <: A
        @A_fields
        b1
end

type C <: A
        @A_fields
        c1
end

主要缺点是当您加入A_fields()时,您必须手动更改A的子类型的所有构造函数。