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
How to Change "Return" Key to "Done" on Keyboard with Swiftui
Argument for Generic Parameter Could Not Be Inferred
Dyld: Library Not Loaded: @Rpath/Libswiftcore.Dylib Problem with New Xcode (10.2)
Weak VS Unowned in Swift. What Are the Internal Differences
Using Os_Log to Log Function Arguments, or Other Dynamic Data
Get Larger Facebook Image Through Firebase Login
Understanding the Removerange(_:) Documentation
Xcode 8.2.1 Not Showing Documentation Description on Autocomplete
Deploy App with Pre-Populated Core Data
How to Convert Nsnull to Nil in Swift
Class-Only Generic Constraints in Swift
What Is 'Where Self' in Protocol Extension
Swiftui .Rotationeffect() Framing and Offsetting
Swift Realm, Load the Pre-Populated Database the Right Way
Convert Firdatasnapshot to Custom Type