Construct objects without spelling out their types if the types can be inferred from context.
julia> vec::Vector{Vector{Int}} = construct_from(undef, 3);
julia> vec
3-element Vector{Vector{Int64}}:
#undef
#undef
#undef
construct_from()
may be useful in a number of circumstances.
-
When defining default values for function arguments.
foo(data::Vector{Int} = construct_from()) = ...
-
When defining default values for fields of
@kwdef
structs.Base.@kwdef struct Foo data::Vector{Int} = construct_from() end
-
When initializing typed globals.
data::Vector{Int} = construct_from()
-
When providing a default value for dictionary lookups.
dict = Dict{Int, Vector{Int}}() get(dict, 42, construct_from())
Note. construct_from()
exploits that Julia inserts an implicit convert()
in many circumstances. (Most prominently, a::T = b
is syntactic sugar for a = typeassert(convert(T, b), T)
.) Correspondingly, construct_from()
fails in cases where there is no conversion, or the conversion happens too late.
-
No conversion:
julia> foo(data::Vector{Int}) = data; julia> # Doesn't work because no conversion foo(construct_from()) ERROR: MethodError: no method matching foo(::ConstructFrom.Arguments{...}) julia> # Let's add the conversion ourselves foo(data) = foo(convert(Vector{Int}, data)); julia> # Now it works foo(construct_from()) Int64[]
-
Conversion happens too late:
julia> a = construct_from() push!(a, 42) # <- Julia won't deduce the type of `a` from how it's used later b::Vector{Int} = a ERROR: MethodError: no method matching push!(::ConstructFrom.Arguments{...}, ::Int64)