【问题标题】:Julia custom type assignmentJulia 自定义类型赋值
【发布时间】:2016-07-10 07:38:44
【问题描述】:

我尝试从 julia 中的自定义类型分配多个元素。但是我不知道该怎么做。或者换句话说,我想重载赋值运算符以返回类型中包含的所有元素的元组。

这是所需的行为:

type foo
    a
    b
end

(a,b) = foo(1,2)
a
> 1

这是错误信息:

ERROR: LoadError: MethodError: `start` has no method matching start(::foo)

我的看法是我需要实现某种迭代器来处理分配,但我不知道该怎么做。

编辑

我实现了“start()、done()、next()”函数。现在我担心如何仍然允许我分配类型而不是它的元素。

写作:

a, b = foo(1,2)
a

# returns
> 1

然而:

a = foo(1,2)
a
# returns
> foo(1,2)

这太棒了。因此,朱莉娅认识到,在 等式的左侧 (lhs) 将返回右侧的类型,并且 lhs 上有“n”个元素将从 类型。因此,如果要分配整个类型,则必须将类型分配给 lhs 上的单个元素。就是这样。

【问题讨论】:

    标签: types iterator julia


    【解决方案1】:

    分配使用迭代器协议,因此需要为该类型实现startdonenext

    关于样式的注释,类型名称应该以大写字母开头,并且字段最好是具体类型以提高性能。下面我在Foo中介绍了一个类型参数T。 T 可以是任何类型,但 Foo 的字段具有相同的类型。如果这是为了限制附加类型参数,可以引入或者可以为每个字段分配一个具体类型。

    下面的例子为Foo类型实现了startdonenext

    type Foo{T}
        x::T
        y::T 
        z::T
    end
    Base.start(foo::Foo) = 1
    Base.done(foo::Foo, i) = nfields(foo) < i
    Base.next(foo::Foo, i) = getfield(foo, i), i+1
    

    通过上面的实现,Foo 的内容可以被分配到不同的变量:

    x, y, z = Foo(1, 2, 3)
    

    作为奖励,Foo 现在可以在 forloop 中迭代为:

    for i in Foo(1, 2, 3)
        println(i)
    end
    

    【讨论】:

    • 谢谢你,这就是我想要的。
    • 这个代码不会对Foo.x != 1 造成破坏,不应该是Base.start(foo;:Foo)=1 因为Base.start 返回一个初始迭代器状态,而不是一个值。
    【解决方案2】:

    我不知道如何重载赋值运算符,但是你可以用这个函数返回所有的字段:

    all_fields(x) = [x.(i) for i = 1:nfields(x)]
    

    那你就可以了

    (a,b) = all_fields(foo(1,2))
    

    【讨论】:

    • 非常好。谢谢。
    猜你喜欢
    • 2021-03-25
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多