- Explicit Type Conversions
- Implicit Type Conversions
- Type Tests
- Conditional Type Conversions
- ? Operator Conversion
- Collection Type Conversions
- Forbidden Type Conversions
Type conversions are also called casts and can be either explicit or implicit.
Explicit Type Conversions
All conversions that can lead to loss of data or precision must be explicit in the source code. These are called narrowing conversions. The normal way to convert the type of an expression into another is to use the field access (dot) operator. However, the dot operator has been overloaded to mean different things in different contexts, so an alternative way to cast expressions is needed when another interpretation has precedence. Therefore, the .: operator can also be used.
expr.type
expr.:type
The resulting expression will be null if the conversion fails during runtime. Casts between value types cannot fail at run time.
Implicit Type Conversions
In some cases, the compiler inserts type conversions that were not present in the source code. These implicit conversions are called widening conversions.
It is possible to extend the set of widening conversions by defining a widening converter function.
Type Tests
All objects have a class field that can be used to determine their class. The in operator can be used to determine subclass relations.
public class TestClass { public constructor() { } } public class SubClass extends TestClass { } { SubClass cls(); pln(cls.class); pln(cls in TestClass); }
Output:
Subclass true
Conditional Type Conversions
Type tests and type conversions can be conflated using as expressions in if statements. The basic form is:
if (id as type) consequence alternativeopt
where id is an identifier which should be converted to type. The consequence block is executed if the conversion succeeded and the alternative block otherwise. Inside the consequence block, id is bound to a copy of the outer id and has the static type type.
An extended form is:
if (id as type and expr) consequence alternativeopt
where expr is a boolean expression with other conditions that must also be true for the consequence branch to be chosen.
For example:
{ Object v = Double(1.0); if (v as Double) { v = 2.0; pln(#v); } pln(#v); }
is equivalent to:
{ Object v = Double(1.0); { Double v = v.Double; if (v) { v = 2.0; pln(#v); } } pln(#v); }
Output:
v=2
v=1
? Operator Conversion
You can also convert one type to another by adding a ? operator in front of the type you want to cast to.
Do note that doing this inside a conditional argument behaves as "was this converted successfully?" rather than evaluating the argument itself.
Take the following code as an example:
{ Object boolObject = false; ?bool boolPrim = boolObject; if (boolPrim) { pln("boolPrim evaluated as true"); } else { pln("boolPrim evaluated as false"); } if (?bool boolConvert = boolObject) { pln("Successfully converted boolConvert"); } else { pln("Failed converting into boolConvert"); } ?int boolInt = boolObject; pln(boolInt); if (?int boolIntCast = boolObject) { pln("Successfully converted boolIntCast"); } else { pln("Failed converting into boolIntCast"); } }
Output:
boolPrim evaluated as false
Successfully converted boolConvert
0
Failed converting into boolIntCast
Collection Type Conversions
Widening type conversions of Sets and Sequences are allowed in CM and can be done with the .: operator. An example of a widening cast of a Sequence follows:
Double[] myDoubles = [Double: 3.0, 2.0, 1.0]; Object[] myObjects = myDoubles.:Object[];
Narrowing cast of collections is not supported in CM. To narrow down a sequence to a more specific type the copy function can be used. An example of narrowing of sequences follows:
Object[] myObjects = [Object: Double(3.0), Int(2), Bool(true)]; Number[] myNumbers = myObjects.copy(Number[]);
Forbidden Type Conversions
Casting an object into an ancestor class is not allowed (so-called upcasts), nor is it permissible to cast a type into itself. There is one exception to this rule, though: upcasts are allowed inside tuple expressions.
Comments
0 comments
Please sign in to leave a comment.