Typecasting
Typecasting allows conversion between a
value of one
type to another.
Most typecasting in
LSL actually involves converting values from one type to another. For example, when a
string is cast to an
integer, the string value is converted into a new integer value. The exception is casting between string and
key, because a key is merely a specialized form of string.
We can do typecasting in one of two ways:
Explicit Typecasting |
Implicit Typecasting. In both cases, note that typecasting never modifies a value stored in a
variable or
list; rather, the result of typecasting the value is used in the rest of the
expression.
Explicit Typecasting
Explicit typecasting is the process of converting between variable types by casting them in the form:
(newtype)variable.
For example, to
say an integer:
integer x = 5;
llSay(0, (string)x);
When converting a string to an integer, leading spaces are ignored, as are any characters after the run of digits. For example, all of the following convert to 42:
"42"
" 42" // leading spaces are ignored
"42 is the answer" // text after the number is ignored
"42,123,456" // only the first digit sequence is interpreted
All other strings convert to the value zero.
If you use explicit typecasting, the typecast will show up in the LSL bytecode. So (integer)((integer)a), will result in bytecode typecasting an integer to an integer. Which wastes cpu time and memory; which is detrimental to your script. -- BW
Implicit Typecasting
Implicit typecasts are like explicit typecasts except that the
(type) notation is not actually seen; the compiler does the casting. Implicit typecasting also happens when a value is copied from a list. However, implicit typecasting can lead to unexpected behavior with
mathematical operators.
Explicit typecasting is preferred over implicit typecasting, since it is often easier to see what is actually happening during the type conversion. Plus, explicit typecasting is prone to less compiler bugginess.
LSL supports two implicit typecasts:
integer to
float
string to
key
Note: as of SL 1.12.3 (6), I could also typecast (string) to (vector), and vise-versa. -ziphren
Examples:
float myFloat = 1; // 1 is an integer.
integer myInt = 3;
myFloat = myInt; // No typecasting needed.
string myString = "foobar";
key myKey = myString;
// ^^^ No typecasting needed, but bad coding practice (key variables should always contain UUID values).
// Without implicit typecasting, this is necessary:
float myFloat = (float)1; // or float myFloat = 1.0;
integer myInt = 4;
myFloat = (float)myInt;
// With integer -> float conversion, explicit typecasting is unnecessary since precision is never lost.
Any string can be used where a key value is required, such as storing a value into a variable of type key. Note that keys can only be explicitly typecast to and from strings. To cast a value from any other type to a key, first cast it to a string.
- Many function calls will not compile if (string)my_key isn't explicitly typecast, while others will accept my_key on its own.
- Obviously, a script will not work correctly if it's expecting a key in the form "66864f3c-e095-d9c8-058d-d6575e6ed1b8" and instead gets "hello".
It is important to note that some string values can be interpreted in odd ways when
typecasting. One thing that catches a lot of people is an empty string ("") or a blank space (" "); both cast to the value 0 when converting from a string to an integer. Many other programming languagues have a
NULL value that would be used instead, but
LSL does not.
Implicit typecasting does not work with lists because lists can hold any type of value (except other lists). If a specific type of value is required in a list, it must be explicitly cast to that type or already be of that type. LSL functions (
llParticleSystem and
llSetPrimitiveParams) that read lists and expect specific types will not implicitly cast the list entries. This is why functions that use lists will fail to compile when passed an integer instead of a float.
Types