Scope and status
СсылкаUse this page to declare bindings and understand name lookup, assignment, and lexical capture.
Types covers compatibility and shared inference. Functions and generics covers calls and generic specialization. Pattern forms, module lookup, and protocol resolution belong to their respective chapters.
Declaration syntax
СсылкаNamedLet = "let" "mut"? Identifier (":" Type)? "=" Expression ;Const = "const" Identifier (":" Type)? "=" Expression ;Assignment = AssignmentTarget "=" Expression ;AssignmentTarget = Identifier | MemberAccess | IndexAccess ;
This transcribed excerpt shows named declarations and plain assignment. Pattern forms, compound operators, and statement boundaries have separate grammar productions.
Declaration source observations
СсылкаBinding declaration forms
Each declaration requires an initializer after = and permits a type annotation. A named binding accepts at most one annotation, including an exported binding. Repeating the annotation produces TPZ2001 during parsing.
| Declaration | Binding form |
|---|---|
let | A pattern |
let mut | A single name |
const | A single name |
Причина
An initializer gives every binding a value. One type annotation supplies one expectation without a second spelling or a competing annotation for the same name.
Binding mutability
| Declaration | Binding mutability |
|---|---|
let | Immutable |
let mut | Mutable |
const | Immutable |
Причина
Reassignment is an explicit choice in the declaration. Immutable bindings let readers rely on one assigned value.
Literal const initializers
Integer literals and untagged string literals without interpolation satisfy the constant-expression requirement for const initializers.
Причина
A literal supplies its value without consulting runtime state, so it can be used wherever a constant expression is required.
Const references to let bindings
A const initializer must be a constant expression. Referencing an ordinary let or let mut binding is rejected with TPZ5001.
Причина
An immutable runtime binding can still depend on runtime computation. Rejecting such references keeps constant-expression admission independent of runtime state.
Reserved None binding name
None cannot be a binding name. This includes let mut, const, typed binding patterns, and bare untyped patterns. The parser reports TPZ2012. Write None() for the Option constructor in patterns and values.
Причина
Reserving None keeps absence recognizable in expressions and patterns. A local name cannot silently replace the Option constructor.
Constant expressions and retained values
A const initializer must pass ordinary name and type checking and the constant-expression check. Admitted forms include scalar and Length literals, None(), untagged strings with constant interpolations, available constant bindings, function values, parentheses, unary expressions, binary expressions other than in, arrays without spread, and record literals whose fields are constant expressions. A reference to a let binding, an ordinary function call, or a later constant in the same module is rejected. Const makes the binding immutable. Its data follows collection value semantics. Grouping a callee preserves its operation and receiver. The grouping does not change whether the call is a constant expression.
The numeric call forms are int.and, int.or, int.xor, and int.shift with one constant integer operand, and float.trunc, float.floor, float.ceil, and float.round with no arguments and a constant float receiver. These calls take no explicit type arguments or spreads. Integer operands are supplied positionally. Integer and float arithmetic expressions may supply their receivers.
Compiler-recognized std.typeset.fromScaledPoints and fromMilliPoints calls, Length conversion methods toPt, toMm, toCm, toIn and toScaledPoints, Pt.toMilliPoints, and Em.resolve admit constant operands. The std.typeset constructor recognition requires the generated standard module. Normal type and argument checks still apply. The implementation issue below preserves the permitted function-value expectation. Initialization-pass ordering is not a new language timing guarantee.
Причина
A constant must not depend on runtime state. Grouping a callee preserves its operation and receiver, so it must preserve the same constant-expression decision.
Assignment source observations
СсылкаCollection values
Since 6.0.0, Array, Map, Set, and ByteBuffer are values. Assignment, argument passing, return, and immutable capture each produce an independent value. Storing a value in a record field, collection element, or Map key or value does the same. Changing one value leaves the others unchanged.
The rule applies recursively inside records, enum payloads, Option, and Result. ByteBuffer contains data without host state and follows the same rule.
A write requires one let mut root binding, including writes through nested fields, indices, and collection operations. An immutable binding's data cannot change through an alias. The immutable assignment rule governs the write path. A function cannot change a caller's collection through a parameter. Bind a mutable local and return the changed value when the caller needs it.
An implementation may share storage and copy when a write occurs. A program cannot observe this storage sharing. The rule makes no promise about allocation, time, or space costs.
Shared handles represent host resources. File retains its shared cursor and closed state. A mutable capture shares one variable. A closure's write to that variable is visible outside the closure. A value assigned to another variable before the write remains unchanged.
See immutable assignment, capture observation, parameter bindings, and collection keys. The existing File cursor example and closed handle example show the resource exception.
Причина
Each intent has one representation. Data uses values and host resources use handles. Independent values prevent hidden changes, so results are reproducible and easy to verify. Concurrent work on separate collection values has no data race through shared collection storage. Collections map directly to value representations such as Rust Vec and HashMap.
Assignment target syntax
An assignment target must be an identifier, member access, or index access. Other expression shapes produce TPZ2003 during parsing. The target also undergoes receiver and mutability checks.
Причина
Assignment must identify a location that can receive a value. A temporary result has no binding or element to update.
Assignment requires a mutable root
Direct replacement of an imported binding is rejected during resolution under the import assignment rule. After resolution succeeds, assignment to an immutable binding, or to a member or index rooted in that binding, is rejected with TPZ5003.
Причина
Mutability follows the root binding through field and index access. Adding an access step must not bypass the declaration's mutation rule.
Expected type of assignment
For =, the target type is the expected type of the right-hand expression.
Причина
The destination already determines which values an assignment can store. Reusing that type gives empty or generic values the context they need.
Assignment through optional access
A member or index assignment target whose receiver chain contains optional access ?. is rejected during checking with TPZ5001.
Причина
An optional receiver can be absent, leaving no location to update. An explicit branch makes the skipped update and value evaluation visible.
Assignment through Map indexing
Assignment through a Map index is rejected with TPZ5001. Use the Map mutation API to update that binding's value under collection value semantics.
Причина
Map insertion can add a key as well as replace a value. A named mutation operation makes that behavior explicit without another update spelling.
Scope and capture source observations
СсылкаLexical name lookup
Local name lookup searches active scopes from the innermost outward and selects the first matching binding. Value and type namespaces are searched separately.
Причина
Lexical nesting determines what a name means without depending on the caller. Separate namespaces keep value lookup from selecting a type declaration.
Nested block scope
A nested block introduces a scope. After an inner binding is declared, later references inside the block resolve to it instead of an outer binding of the same name. References outside that block continue to resolve to the outer binding.
Причина
A block bounds the visibility of local names. Temporary names inside it cannot replace the bindings used by surrounding code.
Local initializer scope
Local let, const names become visible after their initializers have been resolved. An existing outer binding of the same name remains visible in the initializer.
Причина
The initializer can use an existing outer value while computing its replacement. The new name becomes usable after that value exists.
Unbound value names
An ordinary value identifier with no binding or built-in definition is rejected with TPZ5002. Namespace heads follow the module lookup rules.
Причина
Every ordinary reference needs a declaration that determines its value. Static rejection prevents execution with an unspecified binding.
Direct top-level forward reads
A top-level let initializer that directly reads a later let binding in the same module is rejected with TPZ3018 during resolution, for both entry and imported files. Declaration order is the statement order in that module.
Причина
A declaration cannot read a runtime value that has not been initialized. Resolving direct reads before execution catches this mistake with the same TPZ3018 identity in entry and imported files. Local unbound-name errors and delayed runtime reads retain their separate TPZ5002 contract.
Lexical capture identity
A function or lambda reference to an outer lexical binding in the same module resolves to that binding’s original declaration.
Причина
A closure's references keep the meaning they had where it was defined. Calling it from a different scope must not retarget those names.
Values observed by existing and escaping closures
Closures that capture the same mutable binding observe its later assignments, including assignments made by another closure. An immutable capture retains its assigned value and cannot be rebound inside the closure. Collection values follow value semantics. Captured values and shared bindings remain available after the creating function returns while a closure retains them.
Причина
A mutable captured binding represents one shared variable. Retaining captured storage while closures exist prevents references from outliving their values.
Initialization through branches, calls, and closures
Module-level let bindings become ready after their initializers complete, and function bindings become ready at their declaration position. A direct initializer read of the same or a later runtime binding is rejected with TPZ3018 during resolution in entry and imported files alike. The direct check follows an if or while condition, a match scrutinee, a for iterator, and the first comprehension source. It does not enter function, lambda, branch, arm, or loop bodies. Short-circuit right operands and optional-call arguments are delayed as well. A delayed reference reads the binding when execution reaches it. Reading before initialization faults with TPZ5002; reading after initialization returns the current value. Merely storing a closure does not evaluate its body.
Причина
Module initialization can perform effects, so source order determines when runtime values become available. Delayed code must check the value when it actually executes.
Redeclaration and nested shadowing
A module-level name may be declared once. Let, const, function, type, and imported declarations participate in the same module name table, and a second declaration is rejected with TPZ3008. Reusing a name in a nested scope is shadowing. A repeated local const is rejected with TPZ5008. The same local scope must also reject a second let or let mut name; the current let pattern path bypasses the checker guard, which is recorded as an implementation limitation. The local let regression retains TPZ5008 as its intended rejection contract.
Причина
A name should identify one declaration within a scope. Rejecting duplicates prevents silent replacement, while nested scopes make shadowing explicit.
Examples and expected results
СсылкаEach example is a complete example. file. The expected success or rejection is independent of future observed output. All examples remain Pending. A source-backed expectation is not an executed result. Negative examples specify the intended cause and phase; their exact diagnostic locations remain unmeasured.
Immutable, mutable, and constant bindings
Ссылкаimport std.iolet start: int = 1let mut count: int = startcount = 2const label = "Topaz"io.writeLine("{label}:{start}:{count}")
Topaz:1:2
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
Topaz:1:2
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 0.
Topaz:1:2
Нет вывода ошибок.
- Пройдено · expected 0; observed 0
- Пройдено · stdout matches the authored expectation
- Пройдено · stderr matches the authored expectation
- Пройдено · stdout matches the authored expectation
- Пройдено · stdout matches the authored expectation
- Пройдено · stdout matches the authored expectation
- Пройдено · stdout matches the authored expectation
An immutable binding cannot be reassigned
Ссылкаlet count: int = 1count = 2
Нет стандартного вывода.error[TPZ5003]: `count` is immutable; declare it with `let mut`
--> example.tpz:2:1
|
2 | count = 2
| ^^^^^
example.tpz: 1 type diagnostic
Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-assignment-to-immutable at
example.tpz:2:1
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 1.
Нет стандартного вывода.
error[TPZ5003]: `count` is immutable; declare it with `let mut`--> example.tpz:2:1|2 | count = 2| ^^^^^example.tpz: 1 type diagnostic
- Пройдено · expected nonzero; observed 1
- Пройдено · stdout matches the authored expectation
- Пройдено · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow
- Пройдено · checking TPZ5003; cause bindings-assignment-to-immutable; primary location asserted; additional diagnostics allow
An ordinary let reference is not a const initializer
Ссылкаlet source: int = 1const frozen: int = source
Нет стандартного вывода.error[TPZ5001]: `const` initializers must be constant expressions (§4)
--> example.tpz:2:21
|
2 | const frozen: int = source
| ^^^^^^
example.tpz: 1 type diagnostic
Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-const-runtime-reference at
example.tpz:2:21
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 1.
Нет стандартного вывода.
error[TPZ5001]: `const` initializers must be constant expressions (§4)--> example.tpz:2:21|2 | const frozen: int = source| ^^^^^^example.tpz: 1 type diagnostic
- Пройдено · expected nonzero; observed 1
- Пройдено · stdout matches the authored expectation
- Пройдено · checking TPZ5001; cause bindings-const-runtime-reference; primary location asserted; additional diagnostics allow
None cannot name a mutable binding
Ссылкаlet mut None = 1
Нет стандартного вывода.error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name
--> example.tpz:1:9
|
1 | let mut None = 1
| ^^^^
example.tpz: 1 diagnostic
Ожидаемый результат
Ожидаемый результат
Этап отклонения parse. Ненулевой код завершения.
bindings-none-name at
example.tpz:1:9
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 1.
Нет стандартного вывода.
error[TPZ2012]: `None` is the Option constructor (§22.1) and cannot be a binding name--> example.tpz:1:9|1 | let mut None = 1| ^^^^example.tpz: 1 diagnostic
- Пройдено · expected nonzero; observed 1
- Пройдено · stdout matches the authored expectation
- Пройдено · checking TPZ2012; cause bindings-none-name; primary location asserted; additional diagnostics allow
A nested binding shadows the outer one
Ссылкаimport std.iolet value: int = 1let nested: string = {let value: string = "inner"value}let original: int = valueio.writeLine("{nested}:{original}")
inner:1
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
inner:1
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 0.
inner:1
Нет вывода ошибок.
- Пройдено · expected 0; observed 0
- Пройдено · stdout matches the authored expectation
- Пройдено · stderr matches the authored expectation
- Пройдено · stdout matches the authored expectation
An ordinary unbound name is rejected
Ссылкаlet copied: int = missing
Нет стандартного вывода.error[TPZ5002]: `missing` is not bound
--> example.tpz:1:19
|
1 | let copied: int = missing
| ^^^^^^^
example.tpz: 1 type diagnostic
Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-unbound-read at
example.tpz:1:19
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 1.
Нет стандартного вывода.
error[TPZ5002]: `missing` is not bound--> example.tpz:1:19|1 | let copied: int = missing| ^^^^^^^example.tpz: 1 type diagnostic
- Пройдено · expected nonzero; observed 1
- Пройдено · stdout matches the authored expectation
- Пройдено · checking TPZ5002; cause bindings-unbound-read; primary location asserted; additional diagnostics allow
A later top-level let is unavailable to a direct initializer
Ссылкаlet before: int = afterlet after: int = 1
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения resolve. Ненулевой код завершения.
module-initializer-not-ready at
example.tpz:1:19
The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.
A lambda refers to an outer binding
Ссылкаimport std.iolet anchor: int = 7let reader: (int) -> int = (value) => anchorlet observed: int = {let anchor: int = 99reader(0)}io.writeLine("{observed}")
7
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
7
Наблюдаемые утверждения · Пройдено · 5.21.3
Код завершения 0.
7
Нет вывода ошибок.
- Пройдено · expected 0; observed 0
- Пройдено · stdout matches the authored expectation
- Пройдено · stderr matches the authored expectation
Two escaping closures share one mutable binding
Ссылкаimport std.iofunction makeCounters() -> { advance: () -> int, read: () -> int } {let mut count: int = 0let advance: () -> int = () => {count += 1count}let read: () -> int = () => countcount = 4{ advance: advance, read: read }}let counters = makeCounters()io.writeLine("{counters.read()}:{counters.advance()}:{counters.read()}")
4:5:5
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
4:5:5
Immutable captures retain independent collection values
Ссылкаimport std.iofunction makeReader() -> () -> string {let mut current: int = 1let snapshot: int = currentlet items: Array<int> = [10]let mut alias: Array<int> = itemslet read: () -> string = () => "{current}:{snapshot}:{items[0]}"current = 2alias[0] = 30read}let read = makeReader()io.writeLine(read())
2:1:10
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:1:10
A closure cannot reassign an immutable capture
Ссылкаfunction makeReader() -> () -> int {let count: int = 1() => {count = 2count}}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-assignment-to-immutable at
example.tpz:4:9
Call a stored closure after its later binding initializes
Ссылкаimport std.iolet read: () -> int = () => laterlet later: int = 7io.writeLine("{read()}")
7
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
7
A skipped branch does not read a later binding
Ссылкаimport std.iolet chosen: int = if (false) { after } else { 2 }let after: int = 7io.writeLine("{chosen}:{after}")
2:7
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:7
The condition is an immediate initializer read
Ссылкаlet chosen: int = if (after) { 1 } else { 2 }let after: bool = true
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения resolve. Ненулевой код завершения.
module-initializer-not-ready at
example.tpz:1:23
The direct module initializer uses the same TPZ3018 resolve contract in entry and imported files. Current SELF rejects this entry source with TPZ5002; the existing receipt remains historical evidence for that earlier identity. The expected rejection and location are retained, and only the diagnostic assertion is limited.
An executed branch faults before a later binding initializes
Ссылкаlet chosen: int = if (true) { after } else { 0 }let after: int = 7
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-direct-forward-read at
example.tpz:1:31
An inner scope may reuse an outer name
Ссылкаimport std.iolet value: int = 1let inner: int = {let value: int = 2value}io.writeLine("{value}:{inner}")
1:2
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
1:2
Module declarations cannot reuse an existing name
Ссылкаlet value: int = 1const value: int = 2
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения resolve. Ненулевой код завершения.
bindings-same-scope-redeclaration at
example.tpz:2:7
A local let duplicate retains the intended static rejection
Ссылкаfunction invalid() -> int {let value: int = 1let value: int = 2value}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-local-same-scope-redeclaration at
example.tpz:3:9
Constant expressions retain independent collection values
Ссылкаimport std.ioconst base: int = 2const bits: int = base.shift(1).or(1)const rounded: int = (2.2).ceil()const data = { label: "value-{base}", values: [base, bits] }let mut alias: Array<int> = data.valuesalias[0] = 9io.writeLine("{data.label}:{bits}:{rounded}:{data.values[0]}")
value-2:5:3:2
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
value-2:5:3:2
A constant cannot read a later same-module constant
Ссылкаconst before: int = afterconst after: int = 7
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-direct-forward-read at
example.tpz:1:21
A permitted named function value remains the expected constant value
Ссылкаimport std.iofunction answer() -> int { 7 }const saved: () -> int = answerio.writeLine("{saved()}")
7
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
7
Store the function value after its declaration executes
Ссылкаimport std.iofunction answer() -> int { 7 }let saved: () -> int = answerio.writeLine("{saved()}")
7
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
7
The local const path checks duplicate names
Ссылкаfunction invalid() -> int {const value: int = 1const value: int = 2value}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-local-same-scope-redeclaration at
example.tpz:3:11
Repeat a let annotation
Ссылкаlet answer: int: int = 1
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения parse. Ненулевой код завершения.
bindings-duplicate-type-annotation at
example.tpz:1:16
Repeat an exported let annotation
Ссылкаexport let answer: int: int = 1
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения parse. Ненулевой код завершения.
bindings-duplicate-type-annotation at
example.tpz:1:23
Repeat a mutable binding annotation
Ссылкаlet mut answer: int: int = 1
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения parse. Ненулевой код завершения.
bindings-duplicate-type-annotation at
example.tpz:1:20
Repeat a constant annotation
Ссылкаconst answer: int: int = 1
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения parse. Ненулевой код завершения.
bindings-duplicate-type-annotation at
example.tpz:1:18
Annotate each binding once
Ссылкаlet local: int = 1export let published: int = locallet mut count: int = localconst label: string = "Topaz"export const publishedLabel: string = label
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Проверка принимает программу. Код завершения 0.
Group admitted numeric callees
Ссылкаconst bits: int = ((5).and)(3)const rounded: int = ((2.2).ceil)()
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Проверка принимает программу. Код завершения 0.
Group admitted length callees
Ссылкаimport std.typesetconst physical: Length<Pt> = ((1in).toPt)()const relative: Length<Pt> = ((2em).resolve)(12pt)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Проверка принимает программу. Код завершения 0.
Use admitted calls and a grouped length constructor
Ссылкаimport std.typesetconst bits: int = (5).and(3)const rounded: int = (2.2).ceil()const physical: Length<Pt> = (1in).toPt()const relative: Length<Pt> = (2em).resolve(12pt)const constructed: Length<Pt> = (typeset.fromMilliPoints)(1000)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Проверка принимает программу. Код завершения 0.
An ordinary call remains a runtime computation
Ссылкаfunction answer() -> int { 3 }const direct: int = answer()
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-const-ordinary-call at
example.tpz:2:21
Grouping does not make an ordinary call constant
Ссылкаfunction answer() -> int { 3 }const grouped: int = (answer)()
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
bindings-const-ordinary-call at
example.tpz:2:22
Assignment keeps array values independent
Ссылкаimport std.iolet a = [1, 2]let mut b = ab.push(3)io.writeLine("{a.length}:{b.length}")
2:3
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:3
Return a changed local value from a function
Ссылкаimport std.iofunction appended(values: Array<int>) -> Array<int> {let mut local = valueslocal.push(3)local}let items = [1, 2]let changed = appended(items)io.writeLine("{items.length}:{changed.length}")
2:3
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:3
A saved record keeps its collection field
Ссылкаimport std.iolet mut r = { items: [1, 2] }let saved = rr.items[0] = 5io.writeLine("{saved.items[0]}:{r.items[0]}")
1:5
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
1:5
Insert and remove entries in an independent Map value
Ссылкаimport std.iolet entries = map { "one": 1 }let mut changed = entrieschanged.insert("two", 2)io.writeLine("{entries.length}:{changed.length}")changed.remove("one")io.writeLine("{entries.keys[0]}:{changed.keys[0]}")
1:2
one:two
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
1:2one:two
Add and remove members in an independent Set value
Ссылкаimport std.iolet values = set { 1 }let mut changed = valueschanged.add(2)io.writeLine("{values.length}:{changed.length}")changed.remove(1)io.writeLine("{1 in values}:{1 in changed}")
1:2
true:false
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
1:2true:false
A mutable capture changes one variable and preserves earlier values
Ссылкаimport std.iolet mut items = [1]let before = itemslet append: () -> () = () => { items.push(2) }append()io.writeLine("{items.length}:{before.length}")
2:1
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:1