我正在考虑编写类似于NamedArraysImages中定义的类型。假设我实际上只是想要一个带有一部分元数据的数组,说一个用户友好的名称,当我将数组写入磁盘时,它将在文件顶部写入。 (此细节无关紧要;我只是在举一个例子。)

所以我可能会做

type MyNamedArray
    data::Array
    name::ASCIIString
end

function mywrite(f,x::MyNamedArray)
     write(f,x.name)
     write(f,x.data)
end

之类的东西,并且,其他行为不需要与基本Array行为不同。

在我的脑海中,很明显,我只希望对数组操作的每个现有函数都可以在此类型的data字段上进行操作。用另一种语言Java我可能只是对Array进行了子类化,并将name作为实例字段添加到了该子类中,这将自动保持与所有现有Array操作的兼容性。但是在Julia中,如果我尝试上述解决方案,我现在需要定义更多函数,例如就像@TimHoly和'davidavdav'在链接包中所做的一样。

当然,我知道被迫手动编写其中一些功能对于实现您尚未想到的事情很有用。例如。在我上面给出的MyNamedArray示例中,可以通过指出我尚未定义x::MyNamedArray * y::MyNamedArray的名称来反对。但是,如果我只是不关心这一点,并且想要没有太多样板的“可以正常工作”的代码,该怎么办? (例如,参见循环遍历符号以推送新方法定义in NamedArrays并手动写出一百行定义in Images。这些定义中的绝大部分都是样板/“显而易见的”定义。)

具体来说,继续我引用的示例,对于MyNamedArray,默认值可以是x*y不再是MyNamedArray,即,由于每个函数仅默认为对基础数据应用相同功能的“继承”行为,因此我们可以忘记元数据在所有现有功能上。

注意,我发现Tomas Lycken的答案here很有见地,问题和答案here也是有见地的。

我能想到的最好的综合方法是“您只需要吸收它并写出函数,或者编写一个可以为您完成此操作的宏”。如果是这样,那就这样;我只是想知道我是否缺少更好的选择,特别是设计解决方案以使其更像朱利安(Julian)并避免样板的更好方法。

最佳答案

您可以通过简单地将AbstractArray子类化为http://docs.julialang.org/en/latest/manual/interfaces/#abstract-arrays来获得大部分方法。实际上,您可以做一个更好的子类 DenseArray ,它还需要定义一个stride(可能还有pointer)函数,从而使您的自定义数组可以与BLAS一起使用。那只是您需要定义的几种方法。这不是100%,因为许多作者仍然倾向于过度限制只接受Array的方法,以便他们可以轻松接受所有AbstractArrays。在过去两年中,这种情况已经明显改善,并且还在不断改善。

总的来说,我在这里发现非常有用的一种模式是根据抽象父类(super class)型定义接口(interface),并尽可能地放松方法签名。如果不需要分派(dispatch)限制,则可以允许任何类型,只需依靠鸭子输入即可。如果在告诉Julia应该如何处理或依靠其内部实现时仅将分发限制为特定的叶子类型,则您的工作将变得更加可扩展和可重用。

关于oop - 如何避免在Julia中使用大量新的样板?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37686765/

10-09 17:24