Skip to content

Commit

Permalink
assign stmt
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Aug 20, 2024
1 parent 8e88a9b commit 059f754
Showing 1 changed file with 77 additions and 1 deletion.
78 changes: 77 additions & 1 deletion doc/spec-mini.md
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,83 @@ x-- x -= 1

### Assignment statements

TODO
An assignment replaces the current value stored in a [variable](#variables) with a new value specified by an [expression](#expressions). An assignment statement may assign a single value to a single variable, or multiple values to a matching number of variables.

```go
LeftExpresion1[, ...] assign_op RightExpresion1[, ...]
```

Here `assign_op` can be:

```go
= += -= |= ^= *= /= %= <<= >>= &= &^=
```

Each left-hand side operand must be [addressable](#address-operators), a map index expression, or (for = assignments only) the [blank identifier](). Operands may be parenthesized.

```go
x = 1
*p = f()
a[i] = 23
(k) = <-ch // same as: k = <-ch
```

An _assignment operation_ x _op=_ y where op is a binary [arithmetic operator](#arithmetic-operators) is equivalent to x = x op (y) but evaluates x only once. The op= construct is a single token. In assignment operations, both the left- and right-hand expression lists must contain exactly one single-valued expression, and the left-hand expression must not be the blank identifier.

```go
a[i] <<= 2
i &^= 1<<n
```

A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. There are two forms. In the first, the right hand operand is a single multi-valued expression such as a function call, a channel or [map](#map-types) operation, or a [type assertion](). The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values,

```go
x, y = f()
```

assigns the first value to x and the second to y. In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left:

```go
one, two, three = '', '', ''
```

The [blank identifier]() provides a way to ignore right-hand side values in an assignment:

```go
_ = x // evaluate x but ignore it
x, _ = f() // evaluate f() but ignore second result value
```

The assignment proceeds in two phases. First, the operands of [index expressions]() and [pointer indirections]() (including implicit pointer indirections in selectors) on the left and the expressions on the right are all [evaluated in the usual order](). Second, the assignments are carried out in left-to-right order.

```go
a, b = b, a // exchange a and b

x := [1, 2, 3]
i := 0
i, x[i] = 1, 2 // set i = 1, x[0] = 2

i = 0
x[i], i = 2, 1 // set x[0] = 2, i = 1

x[0], x[0] = 1, 2 // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)

x[1], x[3] = 4, 5 // set x[1] = 4, then panic setting x[3] = 5.

i = 2
x = [3, 5, 7]
for i, x[i] <- x { // set i, x[2] = 0, x[0]
break
}
// after this loop, i == 0 and x is [3, 5, 3]
```

In assignments, each value must be [assignable]() to the type of the operand to which it is assigned, with the following special cases:

* Any typed value may be assigned to the blank identifier.
* If an untyped constant is assigned to a variable of interface type or the blank identifier, the constant is first implicitly [converted](#conversions) to its [default type](#constants).
* If an untyped boolean value is assigned to a variable of interface type or the blank identifier, it is first implicitly converted to type bool.


### Empty statements

Expand Down

0 comments on commit 059f754

Please sign in to comment.