arraystypesjulia

How to define a Vector with only integers ≥ 0


As input for a function, I need a Vector with values greater than or equal to zero.

I tried l = Array{>:Unsigned, 1} because Unsigned is subtype of Integer.

However push!(l, 9) throws an error.
MethodError: no method matching push!(::Type{Vector{>:Unsigned}}, ::Int64)

What is the right way to define such an array?

Use case:

function concat_ints(l::Array{Int64, 1})::Int64
    """
    concat_ints([3, 4, 5]) == 345
    """
    @assert all(n -> n ∈ 0:9, l) "Only digits in range 0:9 are allowed inputs"
    s = 0 # sum
    for (i, n) in enumerate(reverse(l))
        s += n * 10^(i-1)
    end
    return s
end

I would like to replace the @assert all(n -> n ∈ 0:9, l) part by enforcing the right input type.


Solution

  • The type you are looking for is probably Array{<:Unsigned, 1}, not Array{>:Unsigned, 1}. But also, l = Array{>:Unsigned, 1} doesn't create a vector of unsigned numbers, it creates a type variable.

    It's like writing t = Int32. That doesn't make t a Int32, it makes t a type variable. Observe:

    julia> t = Int32
    Int32
    
    julia> typeof(t)
    DataType
    
    julia> t = Int32(0)
    0
    
    julia> typeof(t)
    Int32
    

    So what you probably want is l = Vector{UInt}(). Now, only positive values can be pushed into the vector:

    julia> push!(l, 9)
    1-element Vector{UInt64}:
     0x0000000000000009
    
    julia> push!(l, -9)
    ERROR: InexactError: convert(UInt64, -9)
    

    BTW: Using a container like l = Vector{<:Unsigned}() won't work either, since it cannot be instantiated. You could write l = Vector{Unsigned}(), but I wouldn't recommend it, since that would be bad for performance, since the vector has to be able to handle all different sort of unsigned types. Instead, choose a concrete unsigned type like UInt64, UInt32 or so on.