Skip to content

Commit 2c88fb7

Browse files
simonbyrnevtjnashsimeonschaub
authored
Document assignment destructuring (#30579)
* Document assignment destructuring * Add reference to slurping assignment (#37410) * mention swapping variables and other kinds of LHS Co-authored-by: Jameson Nash <vtjnash@gmail.com> Co-authored-by: Simeon Schaub <simeondavidschaub99@gmail.com>
1 parent 4f271b1 commit 2c88fb7

File tree

3 files changed

+94
-16
lines changed

3 files changed

+94
-16
lines changed

base/tuple.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ state `itr_state`. Return a `Tuple`, if `collection` itself is a `Tuple`, a subt
104104
`AbstractVector`, if `collection` is an `AbstractArray`, a subtype of `AbstractString`
105105
if `collection` is an `AbstractString`, and an arbitrary iterator, falling back to
106106
`Iterators.rest(collection[, itr_state])`, otherwise.
107-
Can be overloaded for user-defined collection types to customize the behavior of slurping
108-
in assignments, like `a, b... = collection`.
107+
108+
Can be overloaded for user-defined collection types to customize the behavior of [slurping
109+
in assignments](@ref destructuring-assignment), like `a, b... = collection`.
109110
110111
!!! compat "Julia 1.6"
111112
`Base.rest` requires at least Julia 1.6.

doc/src/manual/functions.md

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,26 @@ Named tuples are very similar to tuples, except that fields can additionally be
352352
using dot syntax (`x.a`) in addition to the regular indexing syntax
353353
(`x[1]`).
354354

355-
## Multiple Return Values
355+
## [Destructuring Assignment and Multiple Return Values](@id destructuring-assignment)
356356

357-
In Julia, one returns a tuple of values to simulate returning multiple values. However, tuples
358-
can be created and destructured without needing parentheses, thereby providing an illusion that
359-
multiple values are being returned, rather than a single tuple value. For example, the following
360-
function returns a pair of values:
357+
A comma-separated list of variables (optionally wrapped in parentheses) can appear on the
358+
left side of an assignment: the value on the right side is _destructured_ by iterating
359+
over and assigning to each variable in turn:
360+
361+
```jldoctest
362+
julia> (a,b,c) = 1:3
363+
1:3
364+
365+
julia> b
366+
2
367+
```
368+
369+
The value on the right should be an iterator (see [Iteration interface](@ref man-interface-iteration))
370+
at least as long as the number of variables on the left (any excess elements of the
371+
iterator are ignored).
372+
373+
This can be used to return multiple values from functions by returning a tuple or
374+
other iterable value. For example, the following function returns two values:
361375

362376
```jldoctest foofunc
363377
julia> function foo(a,b)
@@ -374,8 +388,7 @@ julia> foo(2,3)
374388
(5, 6)
375389
```
376390

377-
A typical usage of such a pair of return values, however, extracts each value into a variable.
378-
Julia supports simple tuple "destructuring" that facilitates this:
391+
Destructuring assignment extracts each value into a variable:
379392

380393
```jldoctest foofunc
381394
julia> x, y = foo(2,3)
@@ -388,15 +401,79 @@ julia> y
388401
6
389402
```
390403

391-
You can also return multiple values using the `return` keyword:
404+
Another common use is for swapping variables:
405+
```jldoctest foofunc
406+
julia> y, x = x, y
407+
(5, 6)
392408
393-
```julia
394-
function foo(a,b)
395-
return a+b, a*b
396-
end
409+
julia> x
410+
6
411+
412+
julia> y
413+
5
414+
```
415+
416+
If only a subset of the elements of the iterator are required, a common convention is to assign ignored elements to a variable
417+
consisting of only underscores `_` (which is an otherwise invalid variable name, see
418+
[Allowed Variable Names](@ref man-allowed-variable-names)):
419+
420+
```jldoctest
421+
julia> _, _, _, d = 1:10
422+
1:10
423+
424+
julia> d
425+
4
426+
```
427+
428+
Other valid left-hand side expressions can be used as elements of the assignment list, which will call [`setindex!`](@ref) or [`setproperty!`](@ref), or recursively destructure individual elements of the iterator:
429+
430+
```jldoctest
431+
julia> X = zeros(3);
432+
433+
julia> X[1], (a,b) = (1, (2, 3))
434+
(1, (2, 3))
435+
436+
julia> X
437+
3-element Vector{Float64}:
438+
1.0
439+
0.0
440+
0.0
441+
442+
julia> a
443+
2
444+
445+
julia> b
446+
3
447+
```
448+
449+
!!! compat "Julia 1.6"
450+
`...` with assignment requires Julia 1.6
451+
452+
If the last symbol in the assignment list is suffixed by `...` (known as _slurping_), then
453+
it will be assigned a collection or lazy iterator of the remaining elements of the
454+
right-hand side iterator:
455+
456+
```jldoctest
457+
julia> a, b... = "hello"
458+
"hello"
459+
460+
julia> a
461+
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)
462+
463+
julia> b
464+
"ello"
465+
466+
julia> a, b... = Iterators.map(abs2, 1:4)
467+
Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4)
468+
469+
julia> a
470+
1
471+
472+
julia> b
473+
Base.Iterators.Rest{Base.Generator{UnitRange{Int64}, typeof(abs2)}, Int64}(Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4), 1)
397474
```
398475

399-
This has the exact same effect as the previous definition of `foo`.
476+
See [`Base.rest`](@ref) for details on the precise handling and customization for specific iterators.
400477

401478
## Argument destructuring
402479

doc/src/manual/variables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ julia> sqrt = 4
9090
ERROR: cannot assign a value to variable Base.sqrt from module Main
9191
```
9292

93-
## Allowed Variable Names
93+
## [Allowed Variable Names](@id man-allowed-variable-names)
9494

9595
Variable names must begin with a letter (A-Z or a-z), underscore, or a subset of Unicode code
9696
points greater than 00A0; in particular, [Unicode character categories](http://www.fileformat.info/info/unicode/category/index.htm)

0 commit comments

Comments
 (0)