How to understand the usage of 'let' or 'var' in Swift? - swift

I'm following tutorial for Swift 4 and have found the usages of 'let' or 'var' in Swift quite inconsistent.
//in try catch : "let ... as" to match a error ?
catch let(or var) printerError as PrinterError
//in switch 1: "let .." to match a case pattern ?
case let(or var) .result(sunrise, sunset):
//in switch 2: "let ... where" pointless for me, why not just use someVar.hasSuffix ?
switch: someVar {
case let x(or var) where x.hasSuffix("pepper"):
Could anyone kindly give a summary of the usage in Swift?
It seems everyone is answering about the difference between 'let' and 'var' and mark the question as a duplication. But, I didn't even mention anything about 'var' in the original post at the first place!

let is keyword that is used to declare a constant value of any data type, using let you can declare a value but you can't change its value again through out the project and if you try to change its value, it will gives you an error stating that this is a let constant. If you want to modify its value kindly change it to var, where var is a keyword used for variables.
let x: Int = 5
let string : String = "Hello! World"
The above values are constant and you can never change these values.
var x: Int = 5
var string: String = "Hello! World"
The above values are variables. You can change their value anywhere in the code.

let is used for constants while var is for variables
let is also used for optional binding like in your examples. You use optional binding to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable.

Let is a keyword to declare a constant.
Think of constant as a box that stores information.
let name = "Bob"
"let" is the keyword to declare the constant.
"name" is the name you assign your constant. This is the box you store your information in. You can name it whatever you want doesn't have to be "name"
"=" assigns the value(your information) from the right side to the "name" constant.
"Bob" is the value aka the information you want to store. It can be anything you want and it's assigned to your constant.
Something you have to remember for constant is that constants are immutable. Meaning the values once declared cannot be changed. That's why it's called constant, because the values are always constant and does not change.

Related

Swift String variable

//First way
var myVar: String = " Hello"
print(myVar)
//Second way
var str = "Hello"
print(str)
I get the same output no matter which of the two I use. What's the difference between them?
These two are basically the same.
When you use var myVar: String = "Hello", you directly tell the swift compiler that your variable is type String.
When you use var myVar = "Hello", you do not specify the type of your variable, so the swift compiler has do do that for you.
Usually, you can get away without declaring your variable type and just have swift do it for you. However, in some cases, namely computed properties and custom classes/structures, you must manually declare your variable to be a specific type.
In your case, either way is fine. The end result is the same, just be aware of the difference for the future.
These two variable are same but with different names :
var myVar
var str
in swift Type doesn't matter that defined because, swift based on value it recognizes what type it is.

What is the different between `if var` and `if let` in swift? [duplicate]

This question already has answers here:
What is the difference between `let` and `var` in Swift?
(32 answers)
Closed 7 years ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Consider this two codes:
if let myValue = myObject.value as NSString?{
//logic here
}
vs
if var myValue = myObject.value as NSString?{
//logic here
}
I know the let keyword is define a constant, is this mean that the first line of code, if the myObject.value is NSString , the myValue constant will be made? This looks confusing.
If you use the let then you will not be able to change myValue.
if let myValue = myObject.value as NSString? {
myValue = "Something else" // <-- Compiler error
}
On the other hand with var you can.
if var myValue = myObject.value as NSString? {
myValue = "Something else" // <-- It's fine
}
Please note that myValue does exists only within the scope of the if and changing its value does not produce effect outside of its scope.
Hope this helps.
You use let to create a constant, so in the first example you cannot change myValue.
When you use var, myValue is a variable which you can change inside the if statement.
The variable type is a different depending if you are using let or var.
let is final and can not be changed afterwards.
var is a normal variable.
Your myValue cannot be changed or modified if you using let in this statement.
“Use let to make a constant and var to make a variable.
The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.
This means you can use constants to name a value that you determine once but use in many places.
var myVariable = 42
myVariable = 50
let myConstant = 42
A constant or variable must have the same type as the value you want to assign to it.
However, you don’t always have to write the type explicitly. Providing a value when you create a constant or variable lets the compiler infer its type.
In the example above, the compiler infers that myVariable is an integer because its initial value is an integer.
Read the : iBook The Swift Programming Language
Thanks .
The example you stated is of Optional Binding
Optional binding is used to determine whether an optional has a value, and if so, to make that value available as a temporary constant or variable.
if let myValue = myObject.value as NSString?{
//logic here
}
Above code will extract myObject.value if exist as a constant, whereas the code below will extract myObject.value as a variable
if var myValue = myObject.value as NSString?{
//logic here
}

Can you declare strings as constants in swift?

Is let name = "string" valid swift code? I thought let only allows a variable to be a constant, but this is obviously type inferred as a string.
Ok, we need to make a distinction.
Mutability
You can declare a constant or a variable.
You declare a constant with the keyword let.
let thisIsNotGoingToChange = 1
thisIsNotGoingToChange = 2 // <- error
You declare a variable with the keyword var:
var thisCouldChange = 1
thisCouldChange = 2 // no problem
So when you ask "Can you declare let variable as a string in swift?" I have to reply: "No".
Because let is a constant and cannot be a variable.
Type
Both constants (let) and variables (var) must have a type and it can be a String.
let thisIsAConstant = "thisStringWillNotChange"
var thisIsAVariable = "thisStringCouldChange"
Hope it helps.
Predefined String values could be defined by let , here is the example and reference for further information.
The: let keyword defines a constant:
let someString = "Some string literal value"
The someString cannot be changed afterwards.
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 it a value exactly once.
Another strange feature:
You can use almost any character you like for constant and variable names, including Unicode characters:
let 🐶🐮 = "yeap!"
To make it short, let is used to define constants and var to define variables
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

Swift: when should I use "var" instead of "let"?

As Apple Documentation says:
Use let to make a constant and var to make a variable. The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once. This means you can use constants to name a value that you determine once but use in many places.
Let's consider some class:
class A {
var a = [String]()
}
Since array a is mutable, it's defined via var. But what if we consider class B, where instance of A is property?
class B {
let b = A()
}
Even if b is mutable, let keyword will be ok, because reference won't be changed. On the other hand, var will be ok too, because content of b can be changed. What should I pick in this example - let or var?
Use let whenever you can. Use var when you must. Making things immutable makes a lot of bugs impossible, so it should be your default choice. As much as possible, set all your values in init and never change them. Similarly, you should use struct when you can, and class when you must (though in my experience this is harder to achieve than using let).
So in your example, if you cannot set A.a during initialization, then yes, it should be var. But there is no need in your example to use var for B.b. (And there's no reason in either example to use class, at least in the way you've presented the question.)
Let's give these better names to help with our reasoning. Let's say
class Head {
var hairs = [String]()
}
class Person {
let head = Head()
}
In this example, a Person has exactly one head, and for the lifetime of each Person, his/her head will always been that same head. However, that head's hairs can grow in, fall out, or otherwise change. Person's ownership of this head has no bearing on the Head's relationship to its hairs.
As Rob mentioned, you should always use let unless you have a good reason not to. Immutability is your friend when it comes to reasoning about program behavior.
Use let when your object does not change its value after has been set a value.
Use var if your object can change its value more than 1 time.
'let' is for constance. 'var' is for something variable.
However, constant restriction is only applied to the object but not its attributes if the object is an instance of class (value are passed by reference). Depending on type of those attributes (constant or variable), we can change their value after. This is not true for structure.
For example:
class VideoMode {
var interlaced = false
var frameRate = 0.0
var name: String?
}
in a function, you declare
let vm = VideoMode()
print("starting framerate is \(vm.frameRate)") // -> print starting framerate is 0.0
vm.frameRate = 20.0
print("framerate now is \(vm.frameRate)") // -> print framerate now is 20.0
//we can change .frameRate later to 10.0, there is no compile error
vm.frameRate = 10.0
print("framerate now is \(vm.frameRate)") // -> print framerate now is 10.0
When you declare a variable with var, it means it can be updated, it is variable, it’s value can be modified.
When you declare a variable with let, it means it cannot be updated, it is non variable, it’s value cannot be modified.
var a = 1
print (a) // output 1
a = 2
print (a) // output 2
let b = 4
print (b) // output 4
b = 5 // error "Cannot assign to value: 'b' is a 'let' constant"
Let us understand above example: We have created a new variable “a” with “var keyword” and assigned the value “1”. When I print “a” I get output as 1. Then I assign 2 to “var a” i.e I’m modifying value of variable “a”. I can do it without getting compiler error because I declared it as var.
In the second scenario I created a new variable “b” with “let keyword” and assigned the value “4”. When I print “b” I got 4 as output. Then I try to assign 5 to “let b” i.e. I’m trying to modify the “let” variable and I get compile time error “Cannot assign to value: ‘b’ is a ‘let’ constant”.
Source: https://thenucleargeeks.com/2019/04/10/swift-let-vs-var/

Using "let" inside Struct - Swift

I'm currently practicing examples from Swift Language iBook. My understanding of "let" is that we use "let" to make a constant. Once we assign a value to it, we cannot assign another value to it again. Like the codes below:
let city="NY"
city="LA" <--error (Cannot assign 'let' value city)
But I saw this example on iBook which really confused me:
struct Color{
let red=0.0, green=0.0, blue=0.0 //<---declare variables using "let" and assign value
init(red:Double,green:Double,blue:Double){
self.red=red //<---assign value to variable again?
self.green=green
self.blue=blue
}
}
In this example, it has already assigned values to red, green and blue which use "let".
Why can we assign values to these three variables again in init?
The initialization in the let provides default values if you don't initialize them yourself in the constructor.
Constructors (init) are special. Inside them, you can assign to a constant instance variable. In fact, if you don't have a default value for them, you have to assign to them. (This applies to classes too.)
Thanks to Qwerty Bob for finding this in the docs
Modifying Constant Properties During Initialization
You can modify the value of a constant property at any point during initialization, as long as it is set to a definite value by the time initialization finishes.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
You may set constant variables during the init process, before the self keyword is used. After this they are then truly 'constant'.
You must do it before the self keyword is used, as if you pass it to another object it could in turn call a method of yours which relies on that constant property
And also: structs get passed by value and not by reference, so you cannot modify the variables in a struct at all after their set. So the let keyword really makes sense.
If you continue reading a few paragraphs after the example you gave from the book (unless they use it in multiple locations), it actually talks about this behavior:
You can modify the value of a constant property at any point during
initialization, as long as it is set to a definite value by the time
initialization finishes.
So basically you can modify constants and upon ending the initialization all constants must have a definitive value. It also goes on to talk about how this works with subclasses too:
For class instances, a constant property can only be modified during
initialization by the class that introduces it. It cannot be modified
by a subclass.
Here is the doc reference for it (same as the book), the quoted sections is under the "Modifying Constant Properties During Initialization" subheading.
Apart from the initialization part, which was answered by Kevin, you're still missing the constant part of let. So to clarify let is not exactly a constant.
According to „The Swift Programming Language.” Apple Inc., 2014-05-27T07:00:00Z. iBooks:
Like C, Swift uses variables to store and refer to values by an
identifying name. Swift also makes extensive use of variables whose
values cannot be changed. These are known as constants, and are much
more powerful than constants in C.
Both var and let are references, therefore let is a const reference.
Using fundamental types doesn't really show how let is different than const.
The difference comes when using it with class instances (reference types):
class CTest
{
var str : String = ""
}
let letTest = CTest()
letTest.str = "test" // OK
letTest.str = "another test" // Still OK
//letTest = CTest() // Error
var varTest1 = CTest()
var varTest2 = CTest()
var varTest3 = CTest()
varTest1.str = "var 1"
varTest2.str = "var 2"
varTest3 = varTest1
varTest1.str = "var 3"
varTest3.str // "var 3"