How to initialize a variable, but once done, its value is final

I'd personally go with @Eendje or @Babul Prabhakar's approach if myPrivateVar was somehow set to nil the setter could still write twice. I wanted to share another option that is guaranteed to never get set twice (as long as the token is never written to!):

    private var token: dispatch_once_t = 0

    private var setOnce : String?

    var publicGetter: String {

        set (newValue) {
            dispatch_once(&token) {
                self.setOnce = newValue
            }
        }

        get {
            guard let setOnce = setOnce else {
                return ""
            }
            return setOnce
        }
    }

The dispatch_once() function provides a simple and efficient mechanism to run an initializer exactly once, similar to pthread_once(3). Well designed code hides the use of lazy initialization. For exam-ple: example:

source


Based on Babul Prabhakar answer, but a bit more clean.

Approach 1:

var test: String? { didSet { test = oldValue ?? test } }

test = "Initial string"
test = "Some other string"
test = "Lets try one last time"

print(test) // "Initial string"

Edit: made it shorter

Approach 2:

let value: String
value = "Initial string"

I guess the second approach is the "built-in" option of Swift to declare a variable once. This is only possible when the variable is assigned right after the declaration though.


What you can do is

private var myPrivateVar:String?;

var publicGetter:String {
    set {
        if myPrivateVar == nil {
            myPrivateVar = newValue;

        }

    }
    get {
        return myPrivateVar!;
    }
}

Swift support lazy variables. For example the following variable will be set to the value "Hi There!" only when accessed.

// variable declaration, not yet initialized
lazy var myString = "Hi There!"


// myString gets initialized here since value is been accessed.
var someOtherVariable = myString

Tags:

Swift