Just curious about a code in Base

Operations on numbers (like UInt32) are never “in place” (since they’re immutable) so the function wouldn’t need the !. The reason for the line a::UInt32 is that, in that context, the type annotation is a “guarantee” that a will always be a UInt32, no matter what happens to it. In practice, this means that every a = a... operation is followed by a convert(UInt32, a).

See:

julia> function foo(x::Int)
           y::Int = x
           y += 1.0
           y
       end
foo (generic function with 1 method)

julia> function bar(x::Int)
           y = x
           y += 1.0
           y
       end
bar (generic function with 1 method)

julia> foo(1)
2

julia> bar(1)
2.0

edit with another example, with a number that cannot be converted back to Int

julia> function baz(x)
           y::Int = x
           y += 1.1
           y
       end
baz (generic function with 1 method)

julia> baz(1)
ERROR: InexactError: Int64(2.1)
Stacktrace:
 [1] Int64 at ./float.jl:710 [inlined]
 [2] convert at ./number.jl:7 [inlined]
 [3] baz(::Int64) at ./REPL[39]:3
 [4] top-level scope at REPL[40]:1
8 Likes