Initializers
Prerequisites: Methods and mutating
An initializer (init) sets up a new instance. Swift guarantees
that every property has a value before an instance can be used.
Custom initializers
struct Temperature {
var celsius: Double
init(celsius: Double) {
self.celsius = celsius
}
init(fahrenheit: Double) {
celsius = (fahrenheit - 32) * 5 / 9
}
}
let a = Temperature(celsius: 25)
let b = Temperature(fahrenheit: 212)
print(a.celsius, b.celsius)
25.0 100.0
Different argument labels let a type offer several clear ways to be
created. Note that writing your own init inside the struct removes
the automatic memberwise initializer. To keep both, put custom
initializers in an extension (a later lesson).
Failable initializers
init? can return nil when the input isn't valid:
struct Email {
let address: String
init?(_ address: String) {
guard address.contains("@"), !address.hasPrefix("@") else {
return nil
}
self.address = address
}
}
let good = Email("ada@example.com")
let bad = Email("not-an-email")
print(good?.address ?? "invalid")
print(bad?.address ?? "invalid")
ada@example.com
invalid
Email(...) returns an Email?. Validating in the initializer means
an Email value, once it exists, is always valid — the rest of your
code never needs to check again. Int("42") is a failable initializer
you've used from the start.
Common mistakes
- Leaving a property without a value in
init:return from initializer without initializing all stored properties. - Calling a method on
selfbefore every property is set.