【问题标题】:Deriving equality for Julia structs with mutable members为具有可变成员的 Julia 结构推导相等性
【发布时间】:2021-06-22 09:11:28
【问题描述】:

在下面的 Julia 代码中,由于 BigInt 是可变结构,我们的相等性不适用于 T{BigInt}。但是,==BigInt 为它们自己明确定义。

julia> struct T{X}
           x :: X
       end

julia> T{Int64}(1) == T{Int64}(1), T{Int64}(1) === T{Int64}(1)
(true, true)

julia> T{BigInt}(1) == T{BigInt}(1), T{BigInt}(1) === T{BigInt}(1)
(false, false)

julia> T{BigInt}(1).x == T{BigInt}(1).x, T{BigInt}(1).x === T{BigInt}(1).x
(true, false)

有没有办法:

  • 为这类结构自动生成==,在每个字段上递归==
  • 或将可变结构的不可变版本作为成员(与 C++ 中的 const 一样),而不是使用与 BigInt 等效的不可变?

我的目标是避免在包含大量此类结构的包中使用样板代码。

【问题讨论】:

    标签: struct julia immutability equality


    【解决方案1】:

    这应该可行:

    function my_equals(a::S, b::S) where S
        for name in fieldnames(S)
            if getfield(a, name) != getfield(b, name)
                return false
            end
        end
        return true
    end
    

    我尝试通过重载==

    import Base.==
    
    function ==(a::S, b::S) where S
        for name in fieldnames(S)
            if getfield(a, name) != getfield(b, name)
                return false
            end
        end
        return true
    end
    

    这具有预期的行为,但(不出所料)似乎会破坏事情(即,在重新定义 == 之后,您甚至不能调用 exit())。

    如果你想使用==,那么你可以让你所有的自定义structs 继承自某个抽象类型,像这样:

    abstract type Z end
    
    struct T{X} <: Z
        x::X
    end
    
    struct S{X} <: Z
        x::X
        y::X
    end
    
    import Base.==
    
    function ==(a::V, b::V) where V <: Z
        for name in fieldnames(V)
            if getfield(a, name) != getfield(b, name)
                return false
            end
        end
        return true
    end
    

    然后就可以使用了

    julia> T{BigInt}(1) == T{BigInt}(1)
    true
    
    julia> S{BigInt}(2, 5) == S{BigInt}(2, 5)
    true
    
    julia> T{BigInt}(1) == T{BigInt}(2)
    false
    
    julia> S{BigInt}(2, 5) == S{BigInt}(2, 3)
    false
    

    这不会干扰现有的==

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2011-11-30
      • 2023-03-15
      • 1970-01-01
      • 2012-03-02
      • 2020-09-06
      相关资源
      最近更新 更多