347 lines
7.8 KiB
Markdown
347 lines
7.8 KiB
Markdown
# 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
|
|
|
|
```text
|
|
T primitif -> valeur by-value
|
|
T struct -> valeur by-value
|
|
T class -> référence de classe
|
|
```
|
|
|
|
### Exemple 2
|
|
|
|
```text
|
|
Array<int32> values = [1, 2, 3];
|
|
Array<int32> empty = [];
|
|
```
|
|
|
|
### Exemple 3
|
|
|
|
```text
|
|
Array<T>::filled(uint64 length, T value)
|
|
```
|
|
|
|
### Exemple 4
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
Array<T>::empty()
|
|
```
|
|
|
|
### Exemple 6
|
|
|
|
```text
|
|
StaticArray<int32, 3> values = [10, 20, 30];
|
|
StaticArray<int32, 0> empty = [];
|
|
```
|
|
|
|
### Exemple 7
|
|
|
|
```text
|
|
StaticArray<T,N>::filled(T value)
|
|
```
|
|
|
|
### Exemple 8
|
|
|
|
```text
|
|
Array<int32> values = ...;
|
|
Slice<int32> part = values::slice(10..<20);
|
|
|
|
part[0] = 42; // modifie values[10]
|
|
```
|
|
|
|
### Exemple 9
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
Iterable<T>
|
|
↓
|
|
Collection<T>
|
|
↓
|
|
List<T>
|
|
↓
|
|
SettableList<T>
|
|
↓
|
|
ResizableList<T>
|
|
```
|
|
|
|
### Exemple 12
|
|
|
|
```text
|
|
count() -> uint64
|
|
isEmpty() -> bool
|
|
contains(const T value) -> bool
|
|
```
|
|
|
|
### Exemple 13
|
|
|
|
```text
|
|
ordre stable
|
|
indexation positionnelle en lecture
|
|
length() -> uint64
|
|
```
|
|
|
|
### Exemple 14
|
|
|
|
```text
|
|
count() == length()
|
|
```
|
|
|
|
### Exemple 15
|
|
|
|
```text
|
|
list[index] = value;
|
|
```
|
|
|
|
### Exemple 16
|
|
|
|
```text
|
|
SettableList<User> users = ...;
|
|
const SettableList<User> readonly = users;
|
|
```
|
|
|
|
### Exemple 17
|
|
|
|
```text
|
|
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>`
|
|
|
|
```text
|
|
interface Iterable<T> {
|
|
const method iterator() -> Iterator<T>;
|
|
}
|
|
|
|
interface Iterator<T> {
|
|
method next() -> Option<T>;
|
|
}
|
|
```
|
|
|
|
### Exemple 19 — `View<T>`
|
|
|
|
```text
|
|
interface View<T> extends Iterable<T> {
|
|
const method count() -> uint64;
|
|
const method isEmpty() -> bool;
|
|
}
|
|
```
|
|
|
|
`View<T>` n'impose pas `contains()`.
|
|
|
|
### Exemple 20 — Set
|
|
|
|
```text
|
|
ResizableSet<T>::add(T value) -> bool
|
|
ResizableSet<T>::remove(const T value) -> bool
|
|
ResizableSet<T>::clear() -> uint64
|
|
```
|
|
|
|
### Exemple 21 — Map
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
map::keys() -> View<K>
|
|
map::values() -> View<V>
|
|
map::entries() -> View<MapEntry<K,V>>
|
|
```
|
|
|
|
### Exemple 23 — Ordre
|
|
|
|
```text
|
|
enum Ordering {
|
|
Less,
|
|
Equal,
|
|
Greater
|
|
}
|
|
|
|
Comparable<T>
|
|
Comparator<T>
|
|
SortedSet<T>
|
|
SortedMap<K,V>
|
|
```
|
|
|
|
### Exemple 24 — Factories ordonnées
|
|
|
|
```text
|
|
TreeSet<T>::natural()
|
|
TreeSet<T>::withComparator(comparator)
|
|
|
|
TreeMap<K,V>::natural()
|
|
TreeMap<K,V>::withComparator(comparator)
|
|
```
|
|
|
|
## Exemples Range
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
Range<uint64> ids = 1..100;
|
|
```
|
|
|
|
### Range 2
|
|
|
|
```text
|
|
NaN interdit comme borne
|
|
+Infinity interdit comme borne
|
|
-Infinity interdit comme borne
|
|
valeur finie autorisée
|
|
```
|
|
|
|
### Range 3
|
|
|
|
```text
|
|
a..a contient exactement a
|
|
a>..a vide
|
|
a..<a vide
|
|
a>..<a vide
|
|
```
|
|
|
|
### Range 4
|
|
|
|
```text
|
|
range::lower()
|
|
range::upper()
|
|
range::includesLower()
|
|
range::includesUpper()
|
|
range::isEmpty()
|
|
range::contains(value)
|
|
```
|
|
|
|
### Range 5
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
(range)::step(step)
|
|
```
|
|
|
|
### Range 7
|
|
|
|
```text
|
|
RangeStep<int32,int32>
|
|
RangeStep<int32,uint32>
|
|
RangeStep<char,uint32>
|
|
RangeStep<Date,Duration>
|
|
```
|
|
|
|
### Range 8
|
|
|
|
```text
|
|
(range)::reverse()
|
|
(range)::reverse()::step(step)
|
|
```
|
|
|
|
### Range 9
|
|
|
|
```text
|
|
range
|
|
[::reverse()]
|
|
[::step(step)]
|
|
```
|
|
|
|
### Range 10
|
|
|
|
```text
|
|
(250u8..255u8)::step(2u8)
|
|
```
|
|
|
|
### Range 11
|
|
|
|
```text
|
|
250 252 254
|
|
```
|
|
|
|
### Range 12
|
|
|
|
```text
|
|
(1..10)::step(4)
|
|
```
|
|
|
|
### Range 13
|
|
|
|
```text
|
|
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\n```text\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\n```text\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\n```text\nVector<int32> values = [1, 2, 3]; // ERROR\n```\n\n### DO — builder explicite\n\n```text\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\n```text\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\n```text\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\n```text\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\n```text\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\n```text\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 |