A type annotation uses `::` to specify a type for a variable or expression. In `name::String`, the name is expected to hold a string. Annotations are especially useful in composite types, where each field can have its own type rather than sharing a broad value type such as `Any` in the dictionary example. section 7.1
Listing 7.1 Definition of a composite type
struct Archer
name::String #1
health::Int #2
arrows::Int #3
end
The `Archer` definition gives its name, health, and arrows fields explicit types. section 7.1
An annotation can also trigger conversion when a value is assigned or returned. Assigning `Int8(10)` to a `Float64` field attempts to convert it; a function annotated to return `UInt8` likewise attempts to convert its result. Conversion is not guaranteed to succeed. section 9.2
julia> foo(x::Int64) :: UInt8 = 2x foo (generic function with 1 method) julia> y = foo(42) 0x54 julia> typeof(y) UInt8
The return annotation makes `foo(42)` produce a `UInt8` value. section 9.2
For reusable composite types, fields can use a type parameter: `struct Vec2D{T}; Δx::T; Δy::T; end`. This avoids writing separate structures for different numeric types. Leaving the field annotations out is possible, but gives up the type checking and memory and performance benefits described for typed fields. section 18.2
















