Swift- Optionals 可选项笔记

这是我参与更文挑战的第3天,活动详情查看: 更文挑战

Optionals

  • 可选项,通常也叫可选类型,它容许将值设置为nil
  • 在类型名称后面加个问号? 来定义一个可选项
var age: Int? = nil
age = 38
复制代码

age 刚开始不表示任何数字,因为你创建一个Person 对象,一开始就知道他的年龄;只有后续赋值给他,才能知道他的值

可选项拆包

可选项有可能含有某一个值,有可能啥也没有

var name: String? = nil
复制代码

当我们使用name.count,真实的string 是有count 数值返回的;但是当nil ,访问的是空内存,此时是没有count 方法的, 着时候Swift是不容许这么调用的

  1. 使用 if let 语法 拆包
if let unwrapped = name {
    print("\(unwrapped.count) letters")
} else {
    print("Missing name.")
}
复制代码
  1. if let 的替代方法 guard let
func greet(_ name: String?) {
    guard let unwrapped = name else {
        print("You didn't provide a name!")
        return
    }
    print("Hello, \(unwrapped)!")
}
复制代码

**guard let** 在函数最开始的时候就 把问题给拦截了,后面就可以开心的调用了

强制拆包 “ !“

let str = "5"
let num = Int(str)
复制代码

如果str 是一个可选项值,swift 会有两种方式让我们选择,要么给str 提供一个默认值 ??

还有一种就是强制拆包语法“ Int(str)!”,这表达是str 肯定能转化成int,但是如果转化不成,则会发生crash

因此,一般只有在你确定安全的情况下才使用这个语法;

可选链语法

Swift 的可选链式调用和 Objective-C 中向 nil 发送消息有些相像,但是 Swift 的可选链式调用可以应用于任意类型,并且能检查调用是否成功。

假如我们访问某个方法,比如: a.b,c , 如果b是可选的;那么可以写成 a.b?.c; 代码运行的时候,swift会检查b的值

如果存在则会调用c,如果返回nil,则c就不会执行了

可选Try

enum PasswordError: Error {
    case obvious
}

func checkPassword(_ password: String) throws -> Bool {
    if password == "password" {
        throw PasswordError.obvious
    }

    return true
}

do {
    try checkPassword("password")
    print("That password is good!")
} catch {
    print("You can't use that password.")
}
复制代码

do, try, catch 正常处理了异常的情况

还有一种方法可以使用 try?

if let result = try? checkPassword("password") {
    print("Result was \(result)")
} else {
    print("D'oh.")
}
复制代码

另外一种就是强制 try! 但你要确保 checkPassword 能是一个正常的函数返回

try! checkPassword("sekrit")
print("OK!")
复制代码

可选初始化失败init? 方法

struct Person {
    var id: String

    init?(id: String) {
        if id.count == 9 {
            self.id = id
        } else {
            return nil
        }
    }
}
复制代码

定义的Person 只有当接收的string 是9位数的时候才能初始化成功,其他时候返回的是一个nil

as?

class Animal { }
class Fish: Animal { }

class Dog: Animal {
    func makeNoise() {
        print("汪汪!")
    }
}
复制代码
let pets = [Fish(), Dog(), Fish(), Dog()]
复制代码

pets 里面有很多小动物,当我们想找到Dog 对象时候,可以使用as? Dog 方法进行类型转化

for pet in pets {
    if let dog = pet as? Dog {
        dog.makeNoise()
    }
}
复制代码

总结

  1. Optionals 让我们以清晰和明确的方式表示值的缺失
  2. 我们可以使用 if let 或者 guard let 进行拆包
  3. 可以使用进行强制拆包
  4. 可以使用 ?? 提供一个默认值
  5. 可选链语法 .? 让调用更简单和安全
  6. 可以使用 try? 转化一个会抛出异常返回值函数,或者强制 try!进行异常处理
  7. 如果你想要初始化方法失败,,使用 init?() 弄一个可选项初始化
  8. 你可以使用类型转化,as将一种类型转化成另一种类型
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享