Swift Difference Between Final Var and Non-Final Var | Final Let and Non-Final Let

swift difference between final var and non-final var | final let and non-final let

The final modifier is described in the Swift Language Reference, which says

final

Apply this modifier to a class or to a property, method, or subscript member of a class. It’s applied to a class to indicate that the class can’t be subclassed. It’s applied to a property, method, or subscript of a class to indicate that a class member can’t be overridden in any subclass.

This means without final we can write:

class A {
var x: Int {return 5}
}
class B : A {
override var x: Int {return 3}
}
var b = B()
assert(b.x == 3)

but if we use final in class A

class A {
final var x: Int {return 5}
}
class B : A {
// COMPILER ERROR
override var x: Int {return 3}
}

then this happens:

$ swift final.swift 
final.swift:6:18: error: var overrides a 'final' var
override var x: Int {return 3}
^
final.swift:2:15: note: overridden declaration is here
final var x: Int {return 5}

final let purpose in Swift, is it not redundant?

It means the variable won't be dynamically dispatched, which can improve performance.

However, if you declare your class final, it's redundant to declare the individual variables/members of that class final.

What is final in Swift

It's not an Access Control Specifier, it's a Declaration Modifier.

final

Apply this modifier to a class or to a property, method, or subscript member of a class. It’s applied to a class to indicate that the class can’t be subclassed. It’s applied to a property, method, or subscript of a class to indicate that a class member can’t be overridden in any subclass.

Source: Swift Language Reference - Declaration – Declaration Modifiers

What is the difference between `let` and `var` in Swift?

The let keyword defines a constant:

let theAnswer = 42

The theAnswer cannot be changed afterwards. This is why anything weak can't be written using let. They need to change during runtime and you must be using var instead.

The var defines an ordinary variable.

What is interesting:

The value of a constant doesn’t need to be known at compile time, but you must assign the value exactly once.

Another strange feature:

You can use almost any character you like for constant and variable
names, including Unicode characters:

let = "dogcow"

Excerpts From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329



Community Wiki

Because comments are asking for adding other facts to the answer, converting this to community wiki answer. Feel free edit the answer to make it better.

What is the difference between final Class and Class?

Final is class modifier which prevents it from being inherited or being overridden. From apple documentation

You can prevent a method, property, or subscript from being overridden
by marking it as final. Do this by writing the final modifier
before the method, property, or subscript’s introducer keyword (such
as final var, final func, final class func, and final subscript).

Any attempt to override a final method, property, or subscript in a
subclass is reported as a compile-time error. Methods, properties, or
subscripts that you add to a class in an extension can also be marked
as final within the extension’s definition.

You can mark an entire class as final by writing the final modifier
before the class keyword in its class definition (final class). Any
attempt to subclass a final class is reported as a compile-time error.

var vs let in Swift

Rather than constant and variable, the correct terminology in swift is immutable and mutable.

You use let when you know that once you assign a value to a variable, it doesn't change - i.e. it is immutable. If you declare the id of a table view cell, most likely it won't change during its lifetime, so by declaring it as immutable there's no risk that you can mistakenly change it - the compiler will inform you about that.

Typical use cases:

  • A constant (the timeout of a timer, or the width of a fixed sized label, the max number of login attempts, etc.). In this scenario the constant is a replacement for the literal value spread over the code (think of #define)
  • the return value of a function used as input for another function
  • the intermediate result of an expression, to be used as input for another expression
  • a container for an unwrapped value in optional binding
  • the data returned by a REST API call, deserialized from JSON into a struct, which must be stored in a database

and a lot more. Every time I write var, I ask myself: can this variable change?. If the answer is no, I replace var with let. Sometimes I also use a more protective approach: I declare everything as immutable, then the compiler will let me know when I try to modify one of them, and for each case I can proceed accordingly.

Some considerations:

For reference types (classes), immutable means that once you assign an instance to the immutable variable, you cannot assign another instance to the same variable.

For value types (numbers, strings, arrays, dictionaries, structs, enums) immutable means that that once you assign a value, you cannot change the value itself. For simple data types (Int, Float, String) it means you cannot assign another value of the same type. For composite data types (structs, arrays, dictionaries) it means you cannot assign a new value (such as a new instance of a struct) and you cannot change any of their stored properties.

Also an immutable variable has a semantic meaning for the developer and whoever reading the code - it clearly states that the variable won't change.

Last, but maybe less important from a pure development point of view, immutables can be subject to optimizations by the compiler.

Why isn't Java variable declared as `final` more often? Compare to let keyword in swift

see In Java, should I use “final” for parameters and locals even when I don't have to?

Basically, for fields, it is useful and also changes their concurrency properties.
see Java concurrency: is final field (initialized in constructor) thread-safe?

However, for local variables and parameters, final's value is less clear. It has some semantic value, but on the other hand, it can also be noise to have

public void foo (final int x, final int y){
try{
final int z = x+y;
}
catch (final Exception z){
final String message = "";
throw new RuntimeException(message);
}
}

compared to

public void foo (int x, int y){
try{
int z = x+y;
}
catch ( Exception z){
String message = "";
throw new RuntimeException(message);
}
}

If you have short methods (which you usually should have), then it is obvious anyway that the variables are not being changed.

Therefore, some developers prefer using final for its semantic value, while others prefer not to use it because of its verbosity.

A comparison of constants and variables in Java and Swift

Using let in Swift is like specifying final in Java, while using var in Swift is like leaving out final in Java.

Swift also have Type Properties that are global to the type. The keyword for type properties is static, so it's exactly the same as in java. If you want a, in java terms, static final field then you write static let, and if you just want a static non-final field you write static var.

Difference between Lazy var and var as-a-closure in Swift

The difference is when the init code for the variable is run. For lazy vars, the init code is run on first access of that variable. For non-lazy vars, it's run when the struct/class is initialized.

struct N {
lazy var a: Int = { print("Setting A"); return 5}();
var b: Int = { print("Setting B"); return 5 }()
}

var n = N()
print(n.a)
print(n.b)

Output:

Setting B
Setting A
5
5

Note how non-lazy b is initialized first. a is only initialized when it's accessed. In either case, the initializer for each property is only run once.



Related Topics



Leave a reply



Submit