在 Julia 中构建非默认构造函数

Posted

技术标签:

【中文标题】在 Julia 中构建非默认构造函数【英文标题】:Building a non-default constructor in Julia 【发布时间】:2014-03-26 09:22:40 【问题描述】:

如何在 Julia 中构建一个输入少于值的构造函数?我有一个 Int64 数字数组,其中每个数字代表 24 个布尔值。最好的情况是我可以发送数组并返回包含每个组件数组的复合类型。这是我尝试过的代码。

type Status
   Valve1::ArrayBool
   Valve2::ArrayBool
   Valve3::ArrayBool
   Valve4::ArrayBool
   Valve5::ArrayBool
   Valve6::ArrayBool
   Valve7::ArrayBool
   Valve8::ArrayBool

   # Constructor for Status type
   function Status(vals::ArrayInt64)
   l = int64(length(vals))

   Valve1 = Array(Bool,l)
   Valve2 = Array(Bool,l)
   Valve3 = Array(Bool,l)
   Valve4 = Array(Bool,l)
   Valve5 = Array(Bool,l)
   Valve6 = Array(Bool,l)
   Valve7 = Array(Bool,l)
   Valve8 = Array(Bool,l)

   # Parse Inputs
   for i=1:l
      # Byte 1
      Valve1[i] = vals[i] & 2^(1-1) > 0
      Valve2[i] = vals[i] & 2^(2-1) > 0
      Valve3[i] = vals[i] & 2^(3-1) > 0
      Valve4[i] = vals[i] & 2^(4-1) > 0
      Valve5[i] = vals[i] & 2^(5-1) > 0
      Valve6[i] = vals[i] & 2^(6-1) > 0
      Valve7[i] = vals[i] & 2^(7-1) > 0
      Valve8[i] = vals[i] & 2^(8-1) > 0
   end # End of conversion

   new(Valve1,Valve2,Valve3,Valve4,Valve5,Valve6,Valve7,Valve8)

   end # End of constructor
end # End of type

这会导致no method convert(TypeBool,ArrayBool,1) 错误。我尝试使用 statuses = Status(StatusW) 实例化它,其中 StatusW 是一个 Int64 值数组。

有用的参考资料:Julia documentation 的 Types 和 Constructors 部分

【问题讨论】:

将定义更改为Valve1::ArrayBool,1 会导致类似的错误。 no method convert(TypeArrayBool,1,Bool) 【参考方案1】:

声明需要如下。

Valve1::VectorBool

另一个造成我困惑的因素是new(Valve1,...) 应该是构造函数中的最后一件事。我在new(Valve1,...) 之后添加了调试println()lines,导致类型返回Nothing

Julia Google Groups 论坛上的 Tim Holy 提供了 solution。

完整的示例应该如下所示。

type Status
    Valve1::VectorBool
    Valve2::VectorBool
    Valve3::VectorBool
    Valve4::VectorBool
    Valve5::VectorBool
    Valve6::VectorBool
    Valve7::VectorBool
    Valve8::VectorBool

    # Constructor for Status type
    function Status(vals::ArrayInt64)
        l = int64(length(vals))

        Valve1 = Array(Bool,l)
        Valve2 = Array(Bool,l)
        Valve3 = Array(Bool,l)
        Valve4 = Array(Bool,l)
        Valve5 = Array(Bool,l)
        Valve6 = Array(Bool,l)
        Valve7 = Array(Bool,l)
        Valve8 = Array(Bool,l)

        # Parse Inputs
        for i=1:l
            # Byte 1
            Valve1[i] = vals[i] & 2^(1-1) > 0
            Valve2[i] = vals[i] & 2^(2-1) > 0
            Valve3[i] = vals[i] & 2^(3-1) > 0
            Valve4[i] = vals[i] & 2^(4-1) > 0
            Valve5[i] = vals[i] & 2^(5-1) > 0
            Valve6[i] = vals[i] & 2^(6-1) > 0
            Valve7[i] = vals[i] & 2^(7-1) > 0
            Valve8[i] = vals[i] & 2^(8-1) > 0
        end # End of conversion

        new(Valve1,Valve2,Valve3,Valve4,Valve5,Valve6,Valve7,Valve8)

    end # End of constructor
end # End of type

【讨论】:

【参考方案2】:

错误消息是正确的,但不幸的是,在 Julia 中很难理解通用的错误消息。

问题是您将字段声明为部分初始化的ArrayBool, N,当您尝试使用ArrayBool, 1 调用构造函数时,这似乎不起作用。

正确的解决方案是将类型声明为包含完全初始化的类型ArrayBool,1 或使用别名VectorBool

您使用的是哪个版本的 Julia?您发布的代码适用于我最新的 Julia 大师,我认为这可能已经在 https://github.com/JuliaLang/julia/issues/4026 解决时得到修复。

【讨论】:

版本 0.2.0 (2013-11-16 23:44 UTC)

以上是关于在 Julia 中构建非默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥显式允许默认构造函数和具有 2 个或更多(非默认)参数的构造函数?

Julia 中的构造函数:根据其他命名字段的输入值初始化命名字段

从测试类调用测试类的非默认构造函数

具有非默认构造函数的 C++ 继承

在 C++ 中使用非默认构造函数初始化对象的成员类

内联使用成员对象的非默认显式构造函数