December 4, 2015
Immutability is great if you can swing it, but sometimes you run into tricky situations, like conditionally initializing an immutable value at the current scope.
func printImmutable(condition: Bool) {
if condition {
let immutable = "condition (\(condition)) is true"
} else {
let immutable = "condition (\(condition)) is false"
}
print(immutable)
}
Xcode barks:
error: use of unresolved identifier ‘immutable’
print(immutable)
Maybe you’ll sacrifice immutability.
func printImmutable(condition: Bool) {
var mutable: String
if condition {
immutable = "condition (\(condition)) is true"
} else {
immutable = "condition (\(condition)) is false"
}
print(mutable)
}
I prefer to keep immutability where I can, so here’s what I’ve decided I like to achieve that goal:
func printImmutable(condition: Bool) {
let immutable = { () -> String in
if condition {
return "condition (\(condition)) is true"
} else {
return "condition (\(condition)) is false"
}
}()
print(immutable)
}
I like this approach because
Another way to solve the problem could look like this:
func printImmutable() {
let immutable = newImmutable()
print(immutable)
}
func newImmutable() -> String {
if 1 > 2 {
return "Swift is broken"
} else {
return "Swift works"
}
}
I prefer reading the closure approach, though both work exactly the same way.
update:
Xcode 6.3 Beta / Swift 1.2 release notes state:
letconstants have been generalized to no longer require immediate initialization. The new rule is that aletconstant must be initialized before use (like avar), and that it may only be initialized: not reassigned or mutated after initialization.
This enables patterns like:
let x: SomeThing
if condition {
x = foo()
} else {
x = bar()
}
use(x)
which formerly required the use of a
var, even though there is no mutation taking place. (16181314)