Files
saselang-bible/examples/022-collections-et-iteration-examples.md
2026-09-13 21:59:15 +02:00

7.8 KiB

Exemples / DO-DON'T — Chapitre 22 — Collections et itération

Document compagnon. Les exemples illustrent les règles du chapitre ; la formulation normative reste dans le chapitre lui-même.

Exemples extraits du chapitre

Exemple 1

T primitif -> valeur by-value
T struct   -> valeur by-value
T class    -> référence de classe

Exemple 2

Array<int32> values = [1, 2, 3];
Array<int32> empty = [];

Exemple 3

Array<T>::filled(uint64 length, T value)

Exemple 4

User firstUser = ...;
User otherUser = ...;

Array<User> users = Array<User>::filled(3, firstUser);
users[1] = otherUser; // OK si l'accès n'est pas const

Exemple 5

Array<T>::empty()

Exemple 6

StaticArray<int32, 3> values = [10, 20, 30];
StaticArray<int32, 0> empty = [];

Exemple 7

StaticArray<T,N>::filled(T value)

Exemple 8

Array<int32> values = ...;
Slice<int32> part = values::slice(10..<20);

part[0] = 42; // modifie values[10]

Exemple 9

reste attachée à la portion qu'elle désigne
conserve une longueur fixe
n'est pas redimensionnable
n'est pas déplaçable vers une autre portion
peut modifier les éléments uniquement si l'accès source l'autorise
ne peut jamais augmenter les droits de mutabilité de la source

Exemple 10

const Array<User> users = ...;
const Slice<User> part = users::slice(0..<4);

part[0] = otherUser;       // ERROR
part[0]::setName("Alice"); // ERROR
part[0]::getName();        // OK

Exemple 11

Iterable<T>
    ↓
Collection<T>
    ↓
List<T>
    ↓
SettableList<T>
    ↓
ResizableList<T>

Exemple 12

count() -> uint64
isEmpty() -> bool
contains(const T value) -> bool

Exemple 13

ordre stable
indexation positionnelle en lecture
length() -> uint64

Exemple 14

count() == length()

Exemple 15

list[index] = value;

Exemple 16

SettableList<User> users = ...;
const SettableList<User> readonly = users;

Exemple 17

StaticArray<T,N>
    List<T>
    SettableList<T>
    pas ResizableList<T>

Array<T>
    List<T>
    SettableList<T>
    pas ResizableList<T>

Slice<T>
    List<T>
    SettableList<T>
    pas ResizableList<T>

Vector<T>
    List<T>
    SettableList<T>
    ResizableList<T>

Exemple 18 — Iterator<T>

interface Iterable<T> {
    const method iterator() -> Iterator<T>;
}

interface Iterator<T> {
    method next() -> Option<T>;
}

Exemple 19 — View<T>

interface View<T> extends Iterable<T> {
    const method count() -> uint64;
    const method isEmpty() -> bool;
}

View<T> n'impose pas contains().

Exemple 20 — Set

ResizableSet<T>::add(T value) -> bool
ResizableSet<T>::remove(const T value) -> bool
ResizableSet<T>::clear() -> uint64

Exemple 21 — Map

map[key] -> V                    // strict
map::get(key) -> Option<V>       // conditionnel
map[key] = value                 // remplacement seulement
map::insert(key, value)          // clé nouvelle, DuplicateKeyFault sinon
map::remove(key) -> V            // clé existante, KeyNotFoundFault sinon
map::clear() -> uint64

Exemple 22 — Vues de Map

map::keys() -> View<K>
map::values() -> View<V>
map::entries() -> View<MapEntry<K,V>>

Exemple 23 — Ordre

enum Ordering {
    Less,
    Equal,
    Greater
}

Comparable<T>
Comparator<T>
SortedSet<T>
SortedMap<K,V>

Exemple 24 — Factories ordonnées

TreeSet<T>::natural()
TreeSet<T>::withComparator(comparator)

TreeMap<K,V>::natural()
TreeMap<K,V>::withComparator(comparator)

Exemples Range

a..b        [a, b]    bornes basse et haute incluses
a>..b       (a, b]    borne basse exclue, borne haute incluse
a..<b       [a, b)    borne basse incluse, borne haute exclue
a>..<b      (a, b)    bornes basse et haute exclues

Range 1

Range<uint64> ids = 1..100;

Range 2

NaN                  interdit comme borne
+Infinity            interdit comme borne
-Infinity            interdit comme borne
valeur finie         autorisée

Range 3

a..a        contient exactement a
a>..a       vide
a..<a       vide
a>..<a      vide

Range 4

range::lower()
range::upper()
range::includesLower()
range::includesUpper()
range::isEmpty()
range::contains(value)

Range 5

Range<T>                         intervalle ordonné
RangeIterable<T>                 parcours canonique vers l'avant
RangeStep<T,Step>                parcours avant avec pas explicite
RangeReverse<T>                  parcours canonique vers l'arrière
RangeReverseStep<T,Step>         parcours arrière avec pas explicite
RangeProgression<T,Step>         valeur de progression produite

Range 6

(range)::step(step)

Range 7

RangeStep<int32,int32>
RangeStep<int32,uint32>
RangeStep<char,uint32>
RangeStep<Date,Duration>

Range 8

(range)::reverse()
(range)::reverse()::step(step)

Range 9

range
    [::reverse()]
    [::step(step)]

Range 10

(250u8..255u8)::step(2u8)

Range 11

250 252 254

Range 12

(1..10)::step(4)

Range 13

1 5 9

DO / DON'T / WHY / compiler error / edge cases

À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.\n\n## Exemples 0.2.18 — Vector / Slice / hashing\n\n### Vector 1 — backing stable et slices\n\ntext\nVector<int32> values = Vector<int32>::builder()\n ::append(10)\n ::append(20)\n ::append(30)\n ::build();\n\nSlice<int32> part = values::slice(0..<2);\n\nvalues::reserve(1000); // part reste valide\nvalues::append(40); // part reste valide\nvalues[0] = 11; // part reste valide et observe 11\n\nvalues::insert(0, 5); // part devient invalide en V1\npart[0]; // SliceInvalidatedFault\n\n\n### Vector 2 — API structurelle\n\ntext\nvalues::append(value); // -> Void\nvalues::insert(index, value); // index <= length()\nT removed = values::removeAt(index);\nuint64 removedCount = values::clear();\n\n\n### DON'T — literal de Vector\n\ntext\nVector<int32> values = [1, 2, 3]; // ERROR\n\n\n### DO — builder explicite\n\ntext\nVector<int32> values = Vector<int32>::builder()\n ::append(1)\n ::append(2)\n ::append(3)\n ::build();\n\n\n### Hash 1 — contrats Core\n\ntext\ninterface Equatable<T> extends OpEqual<T> {\n}\n\ninterface Hashable {\n const method hash(Hasher hasher) -> Void;\n}\n\ninterface Hasher {\n method writeBytes(const Slice<uint8> bytes) -> Void;\n const method finish() -> uint64;\n}\n\n\n### Hash 2 — clé stable\n\ntext\nclass UserKey implements Equatable<UserKey>, Hashable {\n const uint64 id;\n String label;\n\n // == et hash reposent uniquement sur id.\n // label peut changer sans modifier l'identité hashable.\n}\n\n\n### DON'T — identité hashable mutable\n\ntext\nclass BadKey implements Equatable<BadKey>, Hashable {\n String name;\n\n // DON'T si == et hash dépendent de name et que name peut changer.\n}\n\n\n### HashSet / HashMap\n\ntext\nHashSet<T>\n where T implements Equatable<T>\n where T implements Hashable\n\nHashMap<K,V>\n where K implements Equatable<K>\n where K implements Hashable\n\n\nL'ordre d'itération n'est pas garanti. Une collision de hash n'est pas une erreur ; l'égalité distingue les valeurs.\n\n### HashMapBuilder — doublons stricts\n\ntext\nHashMap<String,int32> values = HashMap<String,int32>::builder()\n ::insert("one", 1)\n ::insert("two", 2)\n ::build();\n\nHashMap<String,int32>::builder()\n ::insert("one", 1)\n ::insert("one", 2); // DuplicateKeyFault\n\n