Search code examples
swiftswift3varvariable-declarationlet

How properly declare a variable in Swift?


I found quite interesting these different ways to declare a variable in Swift:

// METHOD 1
var dogName: String = "Charlie"

// METHOD 2
var dogName: String {
    return "Charlie"
}

// METHOD 3
let dogName = {
    return "Charlie"
}

// METHOD 4
var dogName: String = {
    return "Charlie"
}()

Obviously the method 3 declare a let and we known the difference; but why Swift allows the method 4?

What's the difference between these four methods?

I'm quite confusing in particular between method 2 and 4. In addition why the method 3 lose the final brackets compared to method 4?


Solution

  • Method 1 is a standard variable declaration for a String. It has a setter and a getter

    var dogName: String = "Charlie"
    
    print(dogName) -> "Charlie"
    dogName = "Rex" // Valid
    

    Method 2 is a computed property of type String and is read-only

    var dogName: String {
        return "Charlie"
    }
    
    print(dogName) -> "Charlie"
    dogName = "Rex" // Invalid as property is read-only
    

    Method 3 is a read-only property of type () -> String, so basically a lambda function.

    let dogName = {
        return "Charlie"
    }
    
    print(dogName) -> "(Function)"
    print(dogName()) -> "Charlie"
    dogName = "Rex" // Invalid as property is read-only
    

    Method 4 is a closure that will be executed when the containing object is initialised. As it is a var you can replace it with another value

    var dogName: String = {
        return "Charlie"
    }()
    
    print(dogName) -> "Charlie"
    dogName = "Rex" // Valid
    

    That being said, as Method 4 is a closure, you can execute other commands in it. Here is an example where you could use this construct to initialise a UILabel:

    var dogNameLabel: UILabel = {
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
        label.text = "Charlie"
        return label
    }()