as
In the above code, a
is a union of Int32 | String
. If for some reason we are sure a
is an Int32
after the if
, we can force the compiler to treat it like one:
a_as_int = a.as(Int32)
a_as_int.abs # works, compiler knows that a_as_int is Int32
The as
pseudo-method performs a runtime check: if wasn’t an Int32
, an exception is raised.
The argument to the expression is a .
If it is impossible for a type to be restricted by another type, a compile-time error is issued:
You can’t use as
to convert a type to an unrelated type: as
is not like a cast
in other languages. Methods on integers, floats and chars are provided for these conversions. Alternatively, use pointer casts as explained below.
The as
pseudo-method also allows to cast between pointer types:
ptr = Pointer(Int32).malloc(1)
In this case, no runtime checks are done: pointers are unsafe and this type of casting is usually only needed in C bindings and low-level code.
Conversion between pointer types and Reference types is also possible:
The as
pseudo-method can be used to cast an expression to a “bigger” type. For example:
b = a.as(Int32 | Float64)
b # :: Int32 | Float64
The above might not seem to be useful, but it is when, for example, mapping an array of elements:
The Array#map
method uses the block’s type as the generic type for the Array. Without the as
pseudo-method, the inferred type would have been Int32
and we wouldn’t have been able to add a Float64
into it.
Sometimes the compiler can’t infer the type of a block. This can happen in recursive calls that depend on each other. In those cases you can use as
to let it know the type: