Ranges and Spread
The .. and ..= ranges generate sequences of integers. The exclusive form
start..end goes up to end - 1; the inclusive form start..=end includes
the last value. Ranges can be used in for, stored in variables, and used to
slice arrays and strings.
Exclusive and inclusive ranges in for, storing a range in a variable, and array slicing.
// Feature: Range operators `..` (exclusive) and `..=` (inclusive)
// Syntax: `start..end` (up to end-1) and `start..=end` (up to end)
// When to use: generate sequences for `for`, slice arrays/strings.
// Same semantics as Rust and Python (but Python only has `..` via
// `range`).
// Exclusive range — does not include the end.
for i in 0..5 {
print(i)
}
// expected: 0, 1, 2, 3, 4
print("---")
// Inclusive range — includes the end.
for i in 0..=3 {
print(i)
}
// expected: 0, 1, 2, 3
print("---")
// Range can be stored in a variable.
let r = 1..=5
var total = 0
for i in r { total = total + i }
print(total) // 15
// Slicing an array with a range.
let arr = [10, 20, 30, 40, 50]
print(arr[1..3]) // [20, 30] (indices 1 and 2)
print(arr[2..=4]) // [30, 40, 50]
// Counting down: use stdlib (not native). Workaround:
var down = []
for i in 0..5 {
let v = 4 - i
down = [...down, v]
}
print(down) // [4, 3, 2, 1, 0]
// Range size.
var count = 0
for _ in 0..100 { count = count + 1 }
print(count) // 100
The spread operator ... expands an array inside an array literal. It is the
idiomatic way to concatenate arrays or insert elements in the middle of a
sequence. Also use it in function parameters as ...T for variadic functions.
Concatenation with [...a, ...b], shallow copy, and variadic ...int parameter.
// Feature: Spread `...` in array literals
// Syntax: `[...a, ...b]` in array literal (concatenates)
// When to use: copy and/or concatenate arrays without calling
// functions. Important restrictions:
// - Only works in array literals.
// - Does NOT work in destructuring (`let (h, ...t) = ...`).
// - Does NOT work in calls (`f(...arr)` is an error).
// - For varargs in functions, use `...` on the parameter TYPE.
// Concatenate two arrays.
let a = [1, 2, 3]
let b = [4, 5]
let c = [...a, ...b]
print(c) // [1, 2, 3, 4, 5]
// Insert elements between spreads.
let d = [0, ...a, 99, ...b, 100]
print(d) // [0, 1, 2, 3, 99, 4, 5, 100]
// Shallow copy — `[...arr]` creates a new array.
let original = [10, 20, 30]
var copy = [...original]
copy.push(40)
print(original) // [10, 20, 30] (intact)
print(copy) // [10, 20, 30, 40]
// Spread applies to any array-shaped expression.
fn make_seq(n: int) -> [int] {
var result = []
for i in 0..n { result = [...result, i] }
return result
}
let combined = [-1, ...make_seq(3), -2]
print(combined) // [-1, 0, 1, 2, -2]
// Varargs (related topic): `...` goes ON THE TYPE of the parameter.
fn sum_all(nums: ...int) -> int {
var total = 0
for n in nums { total = total + n }
return total
}
print(sum_all(1, 2, 3, 4, 5)) // 15
print(sum_all()) // 0
Challenge
Create two arrays and join them with spread, inserting the number 0 exactly
in the middle. Verify that the original arrays were not modified.
See also