Skip to content

Methods & Iterators

Methods

Attach methods to a record with fn Type.name(self, …). A mut self receiver is passed by reference, so mutations persist; a plain self is by value.

weld
type Counter = { n: int }

fn Counter.inc(mut self) {          # mutates the receiver
    self.n = self.n + 1
}
fn Counter.value(self) -> int {     # reads it (by value)
    return self.n
}

User-defined iterators

A type is iterable if it has a next(mut self) -> T? method — for x in it calls next() until it yields null. This lets you write your own iterators:

weld
type Range = { cur: int, to: int }

fn Range.next(mut self) -> int? {
    if self.cur >= self.to {
        return null                 # null signals "finished"
    }
    let v = self.cur
    self.cur = self.cur + 1
    return v
}

route GET "/odds/:n" (n: int) {
    var odds = Counter { n: 0 }
    let r = Range { cur: 0, to: n }
    for x in r {                    # drives Range.next()
        if x % 2 != 0 {
            odds.inc()
        }
    }
    respond "there are {odds.value()} odd numbers in 0..{n}"
}

Because a for loop only needs next(), methods, generics, and iterators compose into containers written in Weld itself — examples/hashmap.weld is an open-addressing hash map with no built-in help. See Generics & Interfaces.