Search code examples
testingjuliaequality

How to create equality test case for custom structures in julia


I have created a struct

mutable struct mystruct
    x::Float64
    i::Int
end

Now when I initialize it using function x_init:

function x_init(x::Number,i::Int)::mystruct
    x = float(x)
    Z = mystruct(x,i)
    return Z
end

On running this function I get

julia> x_init(2,3)
mystruct(2.0, 3)

But on testing @test x_init(2,3) == mystruct(2.0, 3) I get false.

I expected to get true.

Could someone please explain why I got false and how I should write a test-case for such functions?

I can test like

x_init(2,3).x == mystruct(2.0, 3).x && x_init(2,3).i == mystruct(2.0, 3).i

but is there a better method which does not involve checking each variable?


Solution

  • == (Base.:==) is the generic equality operator that you can overload. If you don't overload ==, it falls back to === (Core.:===), which you can't overload. === compares immutable objects by value, but it compares mutable objects by memory address. Although x_init(2,3) and mystruct(2.0, 3) have the same value, those are separate instances of mutable mystruct and thus have different memory addresses.

    This overload will make x_init(2,3) == mystruct(2.0, 3) return true:

    Base.:(==)(a::mystruct, b::mystruct) = a.x===b.x && a.i===b.i
    

    P.S. the ::mystruct annotation in your x_init method header is unnecessary. Return type annotations possibly add a convert step upon return, but the compiler can infer the return type of x_init must be mystruct and will omit the convert step.