How do I find if an object is a Struct, a Dictionary or a NamedTuple?

I wrote simple functions that print structs, dictionaries and named tuples nicely. I would like to write a function that takes a vector and prints each element, calling one of these three functions if the element is a struct, a dictionary or a named tuple. Something like this:

function print_stuff(alist)
    for x in alist
        typx = typeof(x)
        if typx == Struct
            print_struct(x)
        elseif typx == Dictionary
            print_dict(x)
        elseif typx == NamedTuple
            print_named_tuple(x)
        else
            println(x)
        end
    end
end

Of course it does not work. But how can I implement something like this with Julia?

You can use <: to check if a type is a subtype of the abstract types Dict or NamedTuple. Alternatively, you use isa to check if an instance fits those types (in this case, you won’t need to use typeof first). As other commenters have noted, this type-checking also happens during method dispatch, and multimethods are much easier to maintain than an if statement.

Structs aren’t a particular type, so you’ll need something different to check: isstructtype. That method only works on types, not instances.

https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing

1 Like

You can test x isa AbstractDict etc, or typx <: NamedTuple etc.

But what you will frequently see is that instead of making three functions with different names, just three methods of the same function, and then let dispatch sort them out:

my_print(x::AbstractDict) = ... # dictionary printing code
my_print(x::NamedTuple) = ...
my_print(x) = # struct printing code

print_stuff(alist) = foreach(my_print, alist)

A much more elaborate version of this scheme, mostly involving methods of Base.show, controls how printing at the REPL works. Unlike the if block, new methods for new types can be added.

3 Likes