public behaviour lazy<Value>: Value {
private var storage: Value?
// Only `init()` allowed for now
init() {
storage = nil
}
mutating get {
if let containedValue = storage {
return containedValue
} else {
storage = initialValue()
return storage!
}
}
// Note `mutating`
mutating set {
storage = newValue
}
// `initialValue` is a special case of accessor
// If `initialValue` accessor is defined, then such variable
// will need to have an initializer. Otherwise, it will need not to have one.
accessor initialValue() -> Value
}
func basicUsage() {
@lazy var num: Int = 42
print(num)
}
public behavior observed<Value>: Value {
var value = initialValue()
accessor initialValue() -> Value
mutating accessor willSet(newValue: Value) { }
mutating accessor didSet(oldValue: Value) { }
get {
return value
}
// Note `mutating`
mutating set {
willSet(newValue)
let oldValue = value
value = newValue
didSet(oldValue)
}
}
As Chris Lattner stated, declaration form of the current proposal public let [lazy] _: Value { ... }
is a precedent. All Swift type declarations (besides typealiases
) have form of MODIFIERS DATATYPE_KIND NAME<TEMPLATE_PARAMS> BODY
. We can easily follow this pattern. I find this syntax cleaner and more readable, although some may disagree.
var
keyword is not really needed in the current proposal. No support for let
properties is suggested right now. For a future direction, I suggest that let
properties with behaviours differ in that mutable
members cannot be called on them. (Hence mutable set
, for more customization.)
One reason why I moved Value
type parameter to generic parameters is because it's a type, on which the behavious is parametrized, and those types have always been declared like that in Swift. (Consistency, that is.) Behaviours must have exactly one generic parameter.
The other reason is that as a future direction, it's possible to make behaviours accept more generic parameters. I don't include it here, as it goes too far from the current state of things.
- Naming type of a variable together with its behaviour:
@lazy Int
orlazy<Int>
- Functions accepting behaviours:
func acceptLazyVar(lazyInt: @lazy Int)
- Accessing behaviour and its methods:
acceptLazyVar(lazyInt.@lazy)
,[email protected]()
- Multiple behaviours:
@synchronized @lazy var shared: Resource