@head @title Casts

Sometimes you have a value with a general type such as Object, but would like to convert the value to a more specific type (such as Str). You can do this by using casts. @h2 Successful cast

Alore uses the as operator for casts: @example var o as Object -- Declare o to have type Object o = 'foo' o[0] --E: Type check error: Object does not support [ ] (o as Str)[0] -- Ok after casting to Str (result 'f') @end

In the above example o has type Object, but we know that it really refers to a Str value. On the third line we cast the value to Str, allowing us to use all Str operations such as indexing. @h2 Different uses of "as"

The as keyword is also used for declaring the types of variables. If ambiguous, the as is assumed to be a declaration, not a cast. Place a cast within parentheses if it may be confused with a declaration: @example def F() as void var o = 'foo' as Object -- Declaration, not a cast var s = (o as Str) -- Cast; infer type Str for s var s = o as Str --E: Type check error: declaration with an incompatible initializer --E: (cannot assign Object to Str) end @end

To more clearly see why the last variable definition is invalid, we rewrite it to use a separate assignment statement for initialization: @example ... var s as Str s = o --E: Type check error: incompatible types end @end @h2 Failed casts

The as expression checks that the runtime value of the left operand has the expected type, and returns the left operand value unmodified. The type is specified by the right operand. If the operand does not have the expected value, it raises a CastError exception at runtime: @example var o = 'foo' as Object (o as Int) + 2 --E: CastError: Cannot cast from Str to Int @end @h2 The precedence of as

The as operator has a lower precedence than most other operators. Therefore the left operand rarely needs to be within parentheses: @example var a = (obj.method(arg) + 5 as Int) -- The entire expression obj... is the -- left operand of "as" @end @h2 Invalid casts and converting values

Casts never modify the value of the left operand. For example, casting an Int value to Float results in a type check error, not a numeric conversion: @example var i = 1 as Int var f = (i as Float) --E: Type check error: Cast from Int to Float can never succeed @end

The cast can never succeed if the source and target types do not have a subtyping relationship, and the type checker reports this as an error.

The correct way to convert integers to floats is to call Float: @example var i = 1 as Int var f = Float(i) @end

Use Int to perform the inverse conversion: @example var i = Int(2.2) @end @h2 Casts to generic types and dynamic casts

Alore does not support casts to generic types such as Array<Int> or casts to tuple types (other than Tuple). However, the next section discusses dynamic casts which are often a good alternative to the unsupported cast operations.