I’m trying to understand the below behaviour (MWE reduced from a larger set of code). I define an alias for UInt8 called CompositeValue with the intention of storing two values of 4 bits in a single UInt8 in such a way that I can use CompositeValue where it makes sense. I realize that CompositeValue is merely a different name for type UInt8 and might not work as I intend, but will come back to that below.
using Printf
# type = 4 high bits, value = 4 low bits
const CompositeValue = UInt8
type(a::CompositeValue) = a >> 4
value(a::CompositeValue) = a & 0x0f
function Base.show(io::IO, a::CompositeValue)
print(io, "CompositeValue($(type(a)), $(value(a)))")
end
mutable struct S
n::UInt8 # Type is UInt8, not CompositeValue
function S(v::UInt8)
@printf("in constructor: %s\n", v)
return new(v)
end
end
@printf("%s\n", 0x04)
@printf("%s\n", S(0x04))
When I run the code above in Julia 1.5.2 the output is
4
in constructor: 4
S(CompositeValue(0, 4))
I can’t figure out why there isn’t a consistent printing of either the literal integer or as a CompositiveValue(x,y) in three cases? Somehow only the printing of the UInt8 in S is influenced by my (re)definition of Base.show for UInt8/CompositeValue, but not the other two.
Second question is whether there is a better way to have a type CompositeValue that consists of two 4-bit values in Julia? In C/C++ I would use a bitfield. I found BitsFields.jl, but that doesn’t seem to have been updated for at least 9 months, making me a bit wary to use it. Any other way to have a custom type that is not a struct for such values? Also, the overloading of printing a UInt8 isn’t particularly nice…