3.9 KiB
6. Types, variables, constantes et scopes
6.1 Typage explicite — V1 REQUIS — FIGÉ
Une variable possède un type explicite.
Pas de var, let ou auto utilisé comme inférence générale de l'identité de type d'une variable.
Les littéraux suivent les règles de contextual typing figées à la section 5.7 ; cela ne constitue pas une inférence générale du type des variables.
6.2 Definite assignment — V1 REQUIS — FIGÉ
Une variable peut être déclarée sans valeur initiale seulement si le compilateur prouve qu'elle est assignée avant toute lecture.
Une constante peut être assignée exactement une fois sur plusieurs chemins si le compilateur prouve l'unicité et la complétude de l'assignation.
6.3 Shadowing — V1 REQUIS — FIGÉ
Le shadowing est interdit tant qu'une déclaration précédente de même nom est visible.
Réutilisation autorisée après fin complète du scope précédent :
{
int32 value = 1;
}
{
int32 value = 2;
}
Deux branches disjointes peuvent réutiliser le même nom.
6.4 Blocs anonymes — V1 REQUIS — FIGÉ
Un bloc exécutable anonyme peut créer un scope à l'intérieur d'une fonction, méthode, clsmethod, construct ou destruct.
Les blocs exécutables anonymes top-level sont interdits dans les sources ordinaires.
6.5 Ordre d'évaluation — V1 REQUIS — FIGÉ
Les opérandes et arguments sont évalués de gauche à droite et une seule fois.
Exemple :
foo(a(), b(), c())
évalue a(), puis b(), puis c().
6.6 Mutabilité et const — V1 REQUIS — FIGÉ
La mutabilité est le comportement normal de Saselang.
Type value = ...;
peut être réassigné et peut servir à appeler les opérations mutantes que son type expose, sous réserve des autres règles du langage.
const Type value = ...;
crée un accès const.
Un accès const :
interdit la réaffectation du binding
interdit toute mutation obtenue uniquement à travers ce binding
n'impose aucune immutabilité globale à l'objet éventuellement référencé
n'affecte pas les autres alias mutables légitimes
Exemple classe/référence :
User a = ...;
const User b = a;
a::setName("John"); // OK
b::setName("John"); // ERROR
b::getName(); // OK et observe la modification faite via a
const qualifie donc un accès, pas l'identité globale ni le stockage physique de l'objet.
6.7 Propagation d'un accès const — V1 REQUIS — FIGÉ
Un accès obtenu uniquement à travers un receiver const reste const.
const User user = ...;
user::address::getCity(); // OK si const method
user::address::setCity("Paris"); // ERROR
Le compilateur ne permet pas d'augmenter les droits d'un accès référence :
const User source = ...;
User mutable = source; // ERROR
La réduction des droits est autorisée :
User source = ...;
const User readonly = source; // OK
Pour une valeur réellement copiée by-value, une copie indépendante peut devenir une nouvelle variable mutable :
const int32 a = 10;
int32 b = a; // OK
b = 20; // OK
La même règle s'applique aux structs lorsqu'une copie by-value indépendante est effectuée selon leur contrat de copie.
6.8 Champs const — V1 REQUIS — FIGÉ EN PRINCIPE
Un champ peut être déclaré const.
class Document {
const User owner;
}
Le champ reçoit sa valeur conformément aux règles de construction et d'assignation unique, puis ne peut plus être réassigné via ce champ.
L'accès obtenu via ce champ est const.
this::owner = other; // ERROR après initialisation
this::owner::setName(...); // ERROR via cet accès
Un autre alias mutable indépendant vers le même objet peut toujours le modifier.
const n'est donc ni un mécanisme d'ownership, ni une garantie d'immutabilité globale, ni un verrou runtime.