Research on Swift Optional

Optional type

I've re-studied various books about the Optional type, so I'll write about it. Please note that it may be hard to see because I will post what I studied as it is It's more of a usage than a usage, so it's better to read other articles about how to use it.

Roughly what is Optional?

--A type that represents either a value or an empty --Basically, nil is not allowed, but if it is allowed, use Optional. --Wrapped is called placeholder type --Use Wrapped by replacing it with a concrete type

//Optional is defined in enum
enum Optional<Wrapped> {
    case uone
    case some(Wrapped)
}

let none = Optional<Int>.none
print(".none: \(String(describing: none))")
let some = Optional<Int>.some(1)
print(".some: \(String(describing: some))")

*Type inference
let some2 = Optional.some(1) // Optional<Int>
let none2: Int? = Optional.none // Optional<Int> nil
// .some can be type inferred.none must be typed Error

var a: Int?
a = nil         //by nil literal assignment.Generate none
a = Optional(1) //By initializer.Generate some
a = 1           //By value assignment.Generate some
let opInt: Int? = nil
let opString: String? = nil

print(type(of: opInt), String(describing: opInt))
print(type(of: opString), String(describing: opString))
// Optional<Int> nil
// Optional<String> nil

*By initializer.Generate some*

let opInt2 = Optional(1)
let opString2 = Optional("a")
print(type(of: opInt2), String(describing: opInt2))
print(type(of: opString2), String(describing: opString2))
// Optional<Int> Optional(1)
// Optional<String> Optional("a")

*By value assignment.Generate some*

let opInt3: Int? = 1
print(type(of: opInt3), String(describing: opInt3))
// Optional<Int> Optional(1)
//Unwrap
// Optional<Wrapped>Because the type may not have a value
//Cannot be treated like Wrapped variables and constants
// Int?Operation between types becomes error
let aa: Int? = 1
let bb: Int? = 1
// aa +bb This is an error
/*
 Optional<Wrapped>To perform an operation on a Wrapped type value that a type value has
 Optional<Wrapped>Need to extract from type value to Wrapped type
The operation of retrieving a Wrapped type value is called unwrapping.
 */

*Important place

//Optional binding
// ??operator
//Forced unwrap

*Optional binding
/*
Optional for conditional branching and iterative statement conditions<Wrapped>Have a type value
Within the branch where the existence of the value guarantees, you can directly access the value of type Wrapped.
 if-let statement
if let constant name Optional<Wrapped>Type value{
Statement executed if the value exists
 }
 */

let optionalA = Optional("a") // String?Type
if let a = optionalA {
    print(type(of: a)) //Only executed when optionalA has a value
}
// String

* ??operator
//Show default value if value does not exist
let optionalInt: Int? = 1
// let optionalInt: Int? =nil In this case, 3 is displayed
let int = optionalInt ?? 3 // 1

*Forced unwrap
/*
 Optional<Wrapped>How to force a Wrapped value from a type
Compulsory means that if the value does not exist, an execution error will occur.
 !Use operator
 */

let num1: Int? = 1
let num2: Int? = 1
//How to do forced unwrap
num1! + num2! // 2

/*
Forced unwrap ignores cases with no value, so there is a risk of error
Avoid heavy use
When the existence of the value is very clear,
When the value does not exist, basically avoid using it except where you want to terminate the program
 */

*Optional chain
// Optional<Double>To access the Double isInfinite property from a type
//Doing optional binding

let optionalDouble = Optional(1.0)
let optionalIsInfinite: Bool?

if let double = optionalDouble {
    optionalIsInfinite = double.isInfinite
} else {
    optionalIsInfinite = nil
}
print(String(describing: optionalIsInfinite))

/*
You can use the optional chain to access Wrapped properties and methods without unwrapping.
Optional when using the optional chain<Wrapped>After the four seasons? Followed by
Describe Wrapped type properties and method names
 Optional<Wrapped>If the variable or constant of type is nil?Nil is returned without accessing the properties and methods described below.
Original Optional<Wrapped>The fact that the type expression has no value
This is because there are no properties or methods to access, and there are no values to return.
In the example below, the above Code is rewritten using an optional chain. The result is Bool.?Type
 */

let opDouble = Optional(1.0)
let opIsInfinite = opDouble?.isInfinite
print(String(describing: opIsInfinite))

//The example below calls contains
// CountableRange<Int>?Whether the range of the type constant optionalRange contains the specified value
//Judging result is Bool?value

let optionalRange = Optional(0..<10)
let containsSeven = optionalRange?.contains(7)
print(String(describing: containsSeven))

* map flatMap

//Method to convert value without unwrapping
// Int?Execute a closure that doubles the value for the type constant num3,
//As a result Int?Type value Optional(34)Have received

let num3 = Optional(17)
let num4 = num3.map { value in
    value * 2
} // 34
type(of: num4) // Optional<Int>.Type
/*
You can also use map to convert to another type
 Int?Execute a closure that converts Int to String for type num5, resulting in String?Receive 17
 */

let num5 = Optional(17)
let num6 = num5.map { val in
    String(val)
} // "17"
type(of: num6)

// flat(Map
//The return value of the closure will be Optional
let num7 = Optional("17")
let num8 = num7.flatMap { val in
    Int(val)
}
type(of: num8) // Optional<Int>.Type
//point
/*
It is a point that we are performing an operation that is uncertain whether to return a value for a constant whose existence is uncertain.
If this is a Map instead of a flatMap
The final result is a double wrap type and Int??Becomes
 */

let num9 = Optional("17")
let num10 = num9.map { val in
    Int(val)
}

type(of: num10) // Optional<Optional<Int>>.Type
//FlatMap brings together this doubly uncertain state into one.
//Implicit unwrap
// Wrapped!Regarding

var aaa: String? = "aaa"
var bbb: String! = "bbb"

print(type(of: aaa))
print(type(of: bbb))
// Optional<String>
// Optional<String>
var ccc: String! = aaa
var ddd: String? = bbb

//Implicit unwrap results in error for nil
let eee: Int! = 1
eee + 1 //Calculation is possible in the same way as Int type
// var fff: Int! = nil
// fff + 1 //Run-time Error occurs because there is no value
/*
 Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file __lldb_expr_84/Optional.playground, line 224
 Playground execution failed:
 error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
 The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
 */

Summary

--Usually, it is better to use a combination of binding and ?? map flatMap. --Avoid forced unwrapping and implicit unwrapping as they will result in an Error at run time. -Do not use a lot of! --Always think

I studied hard, so I wrote an article for the time being. This time, unlike other articles, the quality is low, so I'm grateful that you just read it.

Recommended Posts

Research on Swift Optional
Compare Java 8 Optional with Swift
[Swift] Acquisition of IDFA on iOS14