65 lines
1.7 KiB
Plaintext
65 lines
1.7 KiB
Plaintext
;; Swift optionals over typed values: T?, ??, !, a test's as, and chaining through a field and a function held in a field.
|
|
|
|
struct Engine
|
|
power: i32
|
|
boost: CFn(i32) -> i32
|
|
|
|
struct Car
|
|
name: str
|
|
engine: Engine?
|
|
spare: i32?
|
|
|
|
fn twice(x: i32) -> i32 = x * 2
|
|
|
|
fn find(xs: [2 i32?], i: i32) -> i32?
|
|
if i < length(xs) then xs[i] else None
|
|
|
|
;; Counts the defaults evaluated, to show ?? evaluates its right side only
|
|
;; when the left holds nothing.
|
|
let calls = 0
|
|
|
|
fn fallback(v: i32) -> i32
|
|
calls += 1
|
|
v
|
|
|
|
fn describe(o: i32?) -> i32
|
|
if o? as g
|
|
g + 100
|
|
elif find([None, Some(5)], 1)? as h
|
|
h
|
|
else
|
|
0
|
|
|
|
fn main()
|
|
let a: i32? = Some(3)
|
|
let n: i32? = None
|
|
println(a ?? 7, n ?? 7)
|
|
;; A chain of defaults is read from the right; an Option default keeps it
|
|
;; an Option.
|
|
println(n ?? n ?? 9)
|
|
let still: i32? = n ?? a
|
|
println(still!)
|
|
;; Short-circuit: fallback runs once, for n.
|
|
println(a ?? fallback(1), n ?? fallback(2), calls)
|
|
;; Above the comparisons, below arithmetic.
|
|
println(n ?? 1 + 1 == 2)
|
|
println(a!)
|
|
println(describe(Some(1)), describe(None))
|
|
let cs: [Car] = [Car{.name "a" .engine Some(Engine{.power 90 .boost twice}) .spare Some(1)},
|
|
Car{.name "b" .engine None .spare None}]
|
|
for i in range(2)
|
|
let c = cs[i]
|
|
let p = c.engine?.power
|
|
let b = c.engine?.boost(21)
|
|
println(c.name, p ?? -1, b ?? -1)
|
|
;; Flat: a field that is itself an Option is not wrapped again.
|
|
let s: i32? = Some(c)?.spare
|
|
println(s ?? -1)
|
|
let xs = [Some(4), None]
|
|
println(xs[0]!, xs[1] ?? 0)
|
|
;; Nested types.
|
|
let v: Vec(i32?) = vec-new(i32?)
|
|
push(v, Some(1))
|
|
push(v, None)
|
|
println(length(v), v[0] ?? 0, v[1] ?? 0)
|