Swift: let is uninitialized but var gets initialized. Why? [duplicate] - swift

This question already has answers here:
Why optional constant does not automatically have a default value of nil [duplicate]
(2 answers)
Why doesn't Swift allow setting value of an optional constant after object initialization?
(2 answers)
Closed 5 years ago.
I'm using playgrounds to learn Swift and I noticed something strange when trying to set optionals on var and let. Below is the code with output:
var num1: Int?
print(num1) //Output: "nil\n"
let num2: Int?
print(num2) //Output: Error: Constant num2 used before initialized
I do not understand why 'var' gets initialized with nil and 'let' is uninitialized when made optional.

var is variable, you can declare it without initialisation. But let is constant, you should initialise it’s value, i.e.
var num1: Int?
print(num1) //Output: "nil\n"
let num2: Int = 20
print(num2)

Related

Constant used before being initialzed [duplicate]

This question already has an answer here:
Constant unassigned optional will not be nil by default
(1 answer)
Closed 4 years ago.
let errorCodestring : String?
if let theError = errorCodestring {
print(theError)
}
In the above code Xcode throws the error:
constant 'errorCodestring'being used before being initialized
What is wrong in the code and how to clear the error?
You have to initialize the constant before using it.
let errorCodestring : String? = nil

Fixing a bug in a ternary-like if-else block [duplicate]

This question already has answers here:
Change in Xcode 10 Playgrounds Variable Initialization change? Are Xcode 10 Playgrounds an interpreter?
(2 answers)
Closed 4 years ago.
Instead of using the ternary operator, I coded a if-else block which doesn't seem to compile... Didn't understand the bug exactly, why isn't it working? Error line is :
error: MyPlayground2.playground:6:1: error: variables currently must have an initial value when entered at the top level of the REPL
var parentAge: Int
And my code:
import UIKit
var parent: String = "mom"
var parentAge: Int
let optOne = 39
let optTwo = 43
if parent == "mom" {
parentAge = optOne
print(parentAge)
} else {
parentAge = optTwo
print(parentAge)
}
error: variables currently must have an initial value when entered at the top level of the REPL
You should either initialise it with optional or assign an initial value if not optional.
var parentAge: Int?
var parentAge: Int = 0
Both of above representation are correct.

Optionals in Swift - not assigning default value for optionals [duplicate]

This question already has answers here:
Why optional constant does not automatically have a default value of nil [duplicate]
(2 answers)
Constant unassigned optional will not be nil by default
(1 answer)
Closed 5 years ago.
let company : String? // = nil
if company == nil {
var newCompany = company ?? "apple"
}
In this code identifier company we need to assign as
let company : String? = nil
but apple documentation is telling that no need for assigning nil value
You declared a constant without a value and without an initializer that can change it, which is nonsensical. The compiler, therefore, warns you that you should initialize the constant.
Change let to var and your code will work fine.

Class Instantiation in Apple Swift [duplicate]

This question already has answers here:
What is the difference between `let` and `var` in Swift?
(32 answers)
Closed 8 years ago.
Why to instantiate a class I have to do it as a constant with let,
class car {
var type: Int?
var wheels: Int?
}
let auto = car()
I can use var as well:
var auto = car()
What is the difference?, thanks
A constant can only be assigned to, or initialized, once:
let constantAuto = car()
constantAuto.type = 1 // changing properties is fine
constantAuto.wheels = 4
constantAuto = car() // error - can't do this
whereas a variable can be assigned to multiple times:
var variableAuto = car()
variableAuto.type = 1 // changing properties is fine here too
// etc
// need to reset:
variableAuto = car()
Essentially, when you know you're only going to need to create the instance once, use let, so the compiler can be more efficient about the code it creates.
if you're using let you're defining a constant, whereas with var you're declaring a variable.
"A constant declaration defines an immutable binding between the constant name and the value of the initializer expression; after the value of a constant is set, it cannot be changed. That said, if a constant is initialized with a class object, the object itself can change, but the binding between the constant name and the object it refers to can’t."
from https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Declarations.html
to sum it up:
you can change the object a variable refers to, but you can't do that to a constant

What does an exclamation mark in a property in Swift language? [duplicate]

This question already has answers here:
What does an exclamation mark mean in the Swift language?
(23 answers)
Swift variable decorations with "?" (question mark) and "!" (exclamation mark)
(1 answer)
Closed 8 years ago.
There are three way to declare a property in Swift:
var optStr: String?
var normStr: String = "normStr"
var exactStr: String!
The first one is property with an optional type, a type that can contain either nil or the String in our case. The second one is a property that always contain the String. It should be initialized in init or in the declaration.
But what about the third way?
var exactStr: String!
I made some experiments in the playground, and it turned out that a function that takes type? can take both type, type? and type! variables as an argument:
var optStr: String?
var normStr: String
var forcedStr: String!
func printStr(str: String?) {
println("str: \(str)")
}
printStr(optStr) //prints: "str: nil"
//printStr(normStr) //doesn't compile as not initialized
printStr(forcedStr) //prints: "str: nil"
optStr = "optStr"; normStr = "normStr"; forcedStr = "forcedStr"
printStr(optStr) //prints "str: optStr"
printStr(normStr) //prints "str: normStr"
printStr(forcedStr) //prints "str: forcedStr"
So why and when should I use type!?
Update: this is not a duplicate of What does an exclamation mark mean in the Swift language?. I'm not asking about unwrapping a variable: I'm asking about declaring a property with an exclamation point (Type!).
It's a variable of type "implicitly-unwrapped optional String". Essentially, every access of implicitStr is treated as if it were written implicitStr! (thus unwrapping the value).
This, of course, will cause a crash if the value is nil. You can still test the implicit optional via if implicitStr != nil, or use it in optional chaining as var foo = implicitStr?.uppercaseString. So you can still use it just as safely as a normal optional; it's just biased toward the case where the value is not nil.
Implicitly-unwrapped optionals are quite useful in cases where the value may not be present at initialization, but are set early and unlikely to become nil again. (For example, a variable you set in -awakeFromNib might reasonably be an implicitly-unwrapped optional.)
Further, since Objective-C methods can return both nil and object types, their return values cannot be modeled as non-optional. To avoid requiring liberal use of forced unwrapping whenever dealing with Cocoa APIs, though, the parameters and return types of Cocoa APIs are usually represented as implicitly-unwrapped optionals.