Julia中的构造函数:根据其他命名字段

时间:2015-05-29 14:38:36

标签: constructor julia compositetype

想象一个构造函数,它接受两个参数并使用两个参数的值初始化3个命名字段。像这样:

type test1
   a
   b
   c
   test1(a,b) = new(a,b,a/b)
end

这很好用,但是如果c的值不是这么简单的表达式怎么办?如果它超过一两行怎么办?或者是一个复杂的列表理解?将c的表达式直接粘贴到new()中是笨拙的,使代码更难阅读(IMO)。我宁愿做这样的事情:

type test1
   a
   b
   c = a/b
   test1(a,b) = new(a,b,c)
end

abtest1(a,b)的调用显然没有定义,所以这不起作用。也许我只是在寻找语法糖。在任何情况下,我都希望在构造函数的参数值已知并且在调用new().之前可以使用它们时更好地理解

有没有更好的方法(比第一个例子更好)去做我在第二个例子中尝试做的事情?

(我认为以下问题及其答案足以提供帮助,但我仍然过多的朱莉娅新手Building a non-default constructor in Julia

编辑:冒着过于具体的风险,我想我会在这个问题出现的实际用例中加入。我正在做一个自适应整合方案。跨越整合边界的每个体积元素被进一步细分。我对" cube"的定义类型如下。我的学生在python中编写了一个工作原型,但我试图在julia中重写它以获得性能提升。

using Iterators
# Composite type defining a cube element of the integration domain
type cube
    pos # floats: Position of the cube in the integration domain
    dx  # float: Edge length of the cube
    verts # float: List of positions of the vertices 
    fvals::Dict # tuples,floats: Function values at the corners of the cube and its children
    depth::Int # int: Number of splittings to get to this level of cube
    maxdepth::Int # Deepest level of splitting (stopping condition)
    intVal # float: this cube's contribution to the integral

    intVal = 0

    cube(pos,dx,depth,maxdepth) = new(pos,dx,
           [i for i in product(0:dx:dx,0:dx:dx,0:dx:dx)],
           [vt=>fVal([vt...]) for vt in [i for i in product(0:dx:dx,0:dx:dx,0:dx:dx)]],
           depth,maxdepth,intVal)
end

2 个答案:

答案 0 :(得分:5)

内部构造函数只是在类型块中出现的函数,其名称与类型相同。这意味着您可以使用function syntax来定义它们。您可以使用简短形式(如上所述),或者您可以使用更详细的块语法:

type test1
   a
   b
   c
   function test1(a,b)
      c = a/b
      return new(a,b,c)
   end
end

new的调用甚至不需要是方法中的最后一个表达式;您可以将其结果分配给中间变量,然后将其返回。

更多详细信息:type块与普通Julia scope一样,只有少数例外:

  • 单独出现或带有类型注释的任何符号都将成为该类型的字段。
  • 函数可以访问特殊的new内置来实例化类型,与类型相同的函数成为内部构造函数。

当您在类型块中放置任何其他赋值时,它们只是在该范围内创建一个局部变量。它不是字段或类型的一部分,而只是可以在构造函数的方法中使用的变量。也就是说,它不是很有用,可能会change in the future

答案 1 :(得分:0)

使用Matt B.的答案我为我的具体用例构建了以下答案。使用函数的块语法更加清晰。

using Iterators
# Composite type defining a cube element of the integration domain
type cube
    pos # floats: Position of the cube in the integration domain
    dx  # float: Edge length of the cube
    verts # tuple: List of positions of the vertices 
    fvals # floats: Function values at the corners of the cube and its children
    depth::Int # int: Number of splittings to get to this level of cube
    maxdepth::Int # Deepest level of splitting (stopping condition)

    function cube(pos,dx,depth,maxdepth)
        verts = [pos+[vt...].*dx for vt in product(0:1,0:1,0:1)]
        fvals = [fVal([vt...]) for vt in verts ]
        return new(pos,dx,verts,fvals,depth,maxdepth)
    end
end