(Optional)
- Optional, also commonly called optional types, allows values to be set to nil
- Add a after the type name
The question mark?
To define an optional
var name: String = "Jack"
name = nil
var age: Int?
age = 10
age = nil
Copy the code
In C, when you declare a variable, it’s automatically given an initial value, which Swift doesn’t do, but Swift’s Optional has a default initial value nil
func test(a) {
var age: Int -->There is no initial value and must be assigned before it can be usedvar weight: Double? -->The default initial value isnil, equivalent to thevar weight: Double? = nil
}
Copy the code
Use scenarios where you might need to use nil
var array = [1.13.45.33]
func get(_ index: Int) -> Int? {
if index < 0 || index > = array.count {
return nil
}
return array[index]
}
print(get(1))// Optional(15)
print(get(-1))// nil
print(get(5)) // nil
Copy the code
Forced Unwrapping
- The alternative is a layer of packaging for other types, which can be thought of as a box
- If it is
nil
So it’s an empty box - If not for
nil
The box contains the type of data to be wrapped
- If it is
var age: Int? // Default is nil
age = 10
age = nil
Copy the code
- If you want to retrieve wrapped data from the options (take out the contents of the box), use this
Exclamation point!
Forced unpack
var speed: Int? = 10
var speedInt: Int = speed!
speedInt + = 10
Copy the code
- If the pair of values is zero
nil
An optional (empty box) for forced unpacking will generate a runtime error
var age: Int?
age!Operation error:Fatal error: Unexpectedly found nil while unwrapping an Optional value: file Optional.xcplaygroundpage
Copy the code
Determines whether the optional option contains a value
let number = Int("123")
if number ! = nil {
print("String conversion to integer successful:\(number!)")}else {
print("String conversion to integer failed")}Copy the code
Optional Binding
- You can use
Optional binding
To determine whether the option contains a value
If it does, it is automatically unpacked, assigns the value to a temporary constant (let) or variable (var), and returns true, otherwise returns false
if let number = Int("123") {
print("String conversion to integer successful:\(number)")
-->Number is after forced unpackingThe Int value
-->Number is only used for this curly bracket}else {
print("String conversion to integer failed")}Copy the code
Used in enumerated values
enum Season: Int {
case spring = 1, summer, autumn, winter
}
if let season = Season(rawValue: 6) { -->It's possible to get the correspondingcaseIf you can't get it, then the result is nullswitch season {
case .spring:
print("the season is spring")
default:
print("the season is other")}}else {
print("no such season")}Copy the code
Note the following equivalents
if let first = Int("4") {
if let second = Int("42") {
if first < second && second < 100 {
print("\(first) < \(second)"100")}}}= = = = = =The equivalent is as follows, with optional bindings separated by commasifJudge conditionsif let first = Int("4"),
let second = Int("42"),
first < second && second < 100 {
print("\(first) < \(second)"100")}Copy the code
Optional bindings are used in the while loop
---->Iterate through the number group, adding up all the integers encountered in the drawing. If you encounter a negative number or non-number, stop the conveniencevar strs = ["10"."20"."abc"."To 30"."30"]
var index = 0
var sum = 0
while let num = Int(strs[index]), num > 0 {
sum + = num
index + = 1
}
print(sum) / / 30
Copy the code
Null merge operator?? (Nil – Coalescing Operator)
public func ?? <T> (optional: T? .defaultValue: @autoclosure(a)throws -> T?). rethrows -> T?
public func ?? <T> (optional: T? .defaultValue: @autoclosure(a)throws -> T) rethrows -> T
Copy the code
a ?? b
a
Must beIs optionalb
It is optional or not optionalb
witha
The storage types must be the same- if
a
Don’t fornil
, return a- if
a
fornil
, return b- if
b
Not optional, returna
When the packet is automatically unpacked
let a: Int? = 1
let b: Int? = 2
let c = a ?? b / / c Int? , Optional(1)
Copy the code
let a: Int? = nil
let b: Int? = 2
let c = a ?? b / / c Int? , Optional(2)
Copy the code
let a: Int? = nil
let b: Int? = nil
let c = a ?? b / / c Int? , nil
Copy the code
let a: Int? = 1
let b: Int = 2
let c = a ?? b / / c Int, 1
Copy the code
let a: Int? = nil
let b: Int = 2
let c = a ?? b / / c Int, 2
Copy the code
If not?? Some of the code is more difficult to write
let a: Int? = nil
let b: Int = 2
let c: Int
if let tmp = a {
c = tmp
} else {
c = b
}
Copy the code
More than one?? Used together
Let’s do it from left to right
let a: Int? = 1
let b: Int? = 2
let c = a ?? b ?? 3 //c is Int, 1
Copy the code
let a: Int? = nil
let b: Int? = 2
let c = a ?? b ?? 3 //c is Int, 1
Copy the code
let a: Int? = nil
let b: Int? = nil
let c = a ?? b ?? 3 //c is Int, 1
Copy the code
?? Use with if let
let a: Int? = nil
let b: Int? = 2
if let c = a ?? b {
print(c)
}
-->Similar to theif a ! = nil || b ! = nil {}
Copy the code
if let c = a, let d = b {
print(c)
print(d)
}
-->Similar to theif a ! = nil && b ! = nil {}
Copy the code
The if statement implements the login
func login(_ info: [String : String]) {
let username: String
if let tmp = info["username"] {
username = tmp
} else {
print("Please enter user name")
return
}
let password: String
if let tmp = info["password"] {
password = tmp
} else {
print("Please enter your password")
return
}
print("User name:\(username)"."Password:\(password)".Login "ing")
}
login(["username": "jack"."password": "123456"])
login(["password": "123456"])
login(["username": "jack"])
* * * * * * * * * * * *Running result Username: Jack Password:123456Login ing please enter user name please enter passwordCopy the code
Guard statement
The above login service is implemented through Guard
func login(_ info: [String : String]) {
guard let username = info["username"] else {
print("Please enter user name")
return
}
guard let password = info["password"] else {
print("Please enter your password")
return
}
print("User name:\(username)"."Password:\(password)".Login "ing")
}
login(["username": "jack"."password": "123456"])
login(["password": "123456"])
login(["username": "jack"])
* * * * * * * * * * *Running result Username: Jack Password:123456Login ing please enter user name please enter passwordCopy the code
Implicitly Unwrapped Optional
- In some cases, an option will always have a value once it has been set
- In this case, you can remove the checking, and you don’t have to unpack it every time you access it, because it makes sure it has a value every time you access it
- You can add one after the type
Exclamation point!
Defines an implicit unpacking option
let num1: Int! = 10 // If you are certain that a variable will never be nil, you can use this declaration,
let num2: Int = num1 // Num1 is optional. Num1 can be unpacked automatically
if num1 ! = nil {
print(num1 + 6)}if let num3 = num1 {
print(num3)
}
Copy the code
If you assign nil to an optional variable of implicit unpack type, a runtime error will occur when that variable is assigned to another variable/constant
let num4: Int! = nil
let num5: Int = num4 -->Num4, num4, num4, num4, num4, num4, num4nil, so thenilAssign to num5:IntNum5 cannot be nullFatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Copy the code
The above case, let a person feel the use of the belt! “Optional” has many risks. In fact, it is safer to use the following way.
var num5: Int = 10
let num5: int = num56
Copy the code
So you can see the errors, if any, at least before the program runs.
In fact, in most scenarios, we also recommend using tape? That’s optional! What is the point of declaring optional?
- If you provide a set of apis for the outside world to use, and expect users to strictly comply with your requirements, do not pass
nil
You can use this if you expect the application to crash when the user misuses it. Other than that, it’s better not to.
String interpolation
Optional The compiler will warn if the string is interpolated or printed directly
var age: Int? = 10
print("My age is \(age)")// String interpolation directly generates a compiler warning
//️String Interpolation a debug description for an optional value; did you mean to make this explicit? ️
Copy the code
There are three common ways to eliminate warnings
var age: Int? = 10
print("My age is \(age!)")
print("My age is \(String(describing: age))")
print("My age is \(age ?? 0)")
Copy the code
Multiple options
var num1: Int? = 10
var num2: Int?? = num1
var num3: Int?? = 10
print(num2 = = num3) // true
Copy the code
num1
,num2
,num3
The structures of are as follows
Look at the following
var num1: Int? = nil
var num2: Int?? = num1
var num3: Int?? = nil
print(num2 = = num3) // false
(num2 ?? 1) ?? 2 / / 1
(num1 ?? 1) ?? 2 / / 2
Copy the code
You can use the LLDB directive frame variable-r or fr V-r to view the internal information of a variable.
So much for the Swift options.