What should be used to create the instances of classes in Swift and why?
please explain the usage of let and var during the instances creation in Swift
below is the code :-
class ConstantTest{
let constant: String
init(constant: String) {
self.constant = constant
}
func printConstant() {
print(constant)
}
}
let constanttest = ConstantTest(constant: "Hello")
constanttest.printConstant()
var test = ConstantTest(constant: "Hie")
test.printConstant()
Use let
if:
class
, if the reference cannot be replaced with another reference); and But if you need to be able to change it at a later point, use var
, such as true variables whose values are not constant (or in the case of reference types, if you need to replace it with another instance). But variables and properties whose values are not set during the initialization process, you have to use var
. For example, lazy
stored properties use var
because their value is not set when the initialization process completes, but only when you first reference it. Another example includes view controllers' references to their outlets that are hooked up only when the view hierarchy is created at a later point.
Needless to say, computed properties use var
, too.
But, if you can use let
, you should do so, as it's easier to write safe code if you know what is a constant and what is a variable. In your example, you'd use let
.
Note: In the case of reference types, like class
types, let
does not mean that that the object itself is necessarily immutable, merely that you cannot replace it with another instance. If you want to enjoy control over whether it's immutable or not, consider using a value type (e.g. a struct
).
Let me see if I can make that final note more clear. Consider:
class Foo {
var value: String
init(value: String) {
self.value = value
}
}
Then the following is permitted:
let obj = Foo(value: "a")
obj.value = "b" // changing mutable property of reference type, Foo, is permitted
But the following is not:
let obj = Foo(value: "a")
obj = Foo(value: "b") // replacing `obj` with a new instance of `Foo`, is not
If you don't want to be able to change value
property, you can define value
to be immutable (or at least, not publicly mutable), e.g.:
class Foo {
let value: String // or `private(set) var value: String`
init(value: String) {
self.value = value
}
}
Or don't define Foo
as class
(a reference type) and instead define it to be a struct
(a value type):
struct Foo {
var value: String
init(value: String) {
self.value = value
}
}
let obj = Foo(value: "a")
obj.value = "b" // this is not permitted, because Foo value-type, `obj`, was declared with `let`, making it immutable
Note, that final example, declaring Foo
as a value type (a struct
) does change it fairly fundamentally, e.g.
var obj1 = Foo(value: "a")
var obj2 = obj1 // this value is a copy of `obj1` not a reference to the same object that `obj1` pointed to
obj1.value = "b"
print("\(obj1.value)") // will print "b"
print("\(obj2.value)") // will print "a"
But value types, while it requires a slightly different mindset to use them, are incredibly useful for easily writing safe code. See WWDC 2015 Building Better Apps with Value Types in Swift.