Creating variables that call a function of the same name
Creating variables that call a function of the same name êŽë š
Available from Swift 5.4
From Swift 5.4 onwards itâs possible to create a local variable by calling a function of the same name. That might sound obscure, but itâs actually a problem we hit all the time.
For example, this creates a struct with a color(forRow:)
method, which gets called and assigned to a local variable called color
:
struct Table {
let count = 10
func color(forRow row: Int) -> String {
if row.isMultiple(of: 2) {
return "red"
} else {
return "black"
}
}
func printRows() {
for i in 0..<count {
let color = color(forRow: i)
print("Row \(i): \(color)")
}
}
}
let table = Table()
table.printRows()
That kind of usage is only allowed from Swift 5.4 and later. In earlier versions of Swift, it would create a circular reference because Swift couldnât distinguish between the local color
constant and the color(forRow:)
method it was calling â you would have seen the error âVariable used within its own initial valueâ.
This usually resulted in us either using self.color(forRow: 1989)
to make it clear we mean the method call, or just naming the local value something else such as colorForRow
.
Fortunately Swift 5.4 resolves this (apple/swift
) and allows us to use the more natural naming.
This change also allows us to make local copies of properties and global variables. For example, we can take a copy of a username
property that is also called username
, like this:
struct User {
let username = "Taylor"
func suggestAlternativeUsername() -> String {
var username = username
username += String(Int.random(in: 1000...9999))
return username
}
}
let user = User()
user.suggestAlternativeUsername()
Because this also applies to global variables, that same code works just fine even without the struct in place:
let username = "Taytay"
func suggestAlternativeUsername() -> String {
var username = username
username += String(Int.random(in: 1000...9999))
return username
}
suggestAlternativeUsername()