zoukankan      html  css  js  c++  java
  • [Swift]Swift5.1速览手册

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(let_us_code)
    ➤博主域名:https://www.zengqiang.org
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/11928467.html
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    英文原文地址:https://www.raywenderlich.com/6362977-swift-5-1-cheat-sheet-and-quick-reference

    声明常量和变量

    • 使用 let 关键字声明一个常量

    let double: Double = 2.0
    // double = 3.0 // 错误:不能给常量重新赋值
    let inferredDouble = 2.0 // 推断为一个 Double 类型

    • 使用 var 关键字声明一个变量

    var mutableInt: Int = 1
    mutableInt = 2 // OK: 可以给一个变量重新赋值

    数值类型转换

    let integerValue = 8
    let doubleValue = 8.0
    //let sum = integerValue + double // 错误:类型不匹配
    // 使用显式的方法来防止隐藏的转换错误并有助于明确类型转换意图
    let sum = Double(integerValue) + double // OK: 两个值有相同类型

    字符串

    • 使用字符串字面量来初始化一个常量或变量

    let helloWorld = "Hello, World!"

    • 使用多行字符串字面量来跨越多行

    let helloWorldProgram = """
    A "Hello, World!" program generally is a computer program
    that outputs or displays the message "Hello, World!"
    """

    • 空字符串

    let emptyString = "" // 使用字符串字面量
    let anotherEmptyString = String() // 初始化语法

    • 修改字符串

    var mutableString = "Swift"
    mutableString += " is awesome!"

    • 字符串插值

    print("The value is (double)") // 插入一个 Double 值
    print("This is my opinion: (mutableString)") // 插入一个字符串

    元组

    • 将多个值组合为一个复合值

    let httpError = (503, "Server Error")

    • 分解元组的内容

    let (code, reason) = httpError

    • 另一种分解方式

    let codeByIndex = httpError.0
    let reasonByIndex = httpError.1

    • 使用 _ 来忽略元组的某些部分

    let (_, justTheReason) = httpError

    可选项

    • catchphrase 可以包含 String 或 nil

    var catchphrase: String? // 由编译器自动设置为nil
    catchphrase = "Hey, what's up, everybody?"

    • 强制解包操作符 (!)

    // 如果 catchphrase 不是nil,count1 包含 catchphrase 的计数值;
    // 否则程序崩溃
    let count1: Int = catchphrase!.count

    • 可选绑定

    // 如果 catchphrase?.count 返回的可选 Int 包含一个值,
    // 则将一个称为 count 的新常量设置为可选中包含的值
    if let count = catchphrase?.count {
      print(count)
    }

    • 合并操作符(??)

    // 如果 catchphrase 不是 nil,count2 包含 catchphrase 的 count 值; 否则为 0
    let count2: Int = catchphrase?.count ?? 0

    • 链式操作符(?)

    // 如果 catchphrase 不是nil,count3 包含 catchphrase 的 count 值; 否则为 nil
    let count3: Int? = catchphrase?.count

    • 隐式展开的可选值

    let forcedCatchphrase: String! = "Hey, what's up, everybody?"
    let implicitCatchphrase = forcedCatchphrase // 无需使用感叹号

    集合类型:Array

    let immutableArray: [String] = ["Alice", "Bob"]
    // mutableArray 的类型为 [String]
    var mutableArray = ["Eve", "Frank"]

    • 测试包含关系

    let isEveThere = immutableArray.contains("Eve")
    let name: String = immutableArray[0] // 通过索引访问

    • 在列表中修改项目;

    // 如果索引越界,则崩溃
    mutableArray[1] = "Bart"
    // immutableArray[1] = "Bart" // 错误:不能修改
    mutableArray.append("Ellen") // 添加项目
    mutableArray.insert("Gemma", at: 1) // 在指定索引处添加项目

    • 通过索引来删除

    let removedPerson = mutableArray.remove(at: 1)
    // 不能重新赋值一个常量集合或修改它的内容
    // 可以重新赋值一个可变集合和修改它的w内容
    mutableArray = ["Ilary", "David"]
    mutableArray[0] = "John"

    集合类型: Dictionary

    let immutableDict: [String: String] = ["name": "Kirk", "rank": "captain"]
    // mutableDict 的类型为 [String: String]
    var mutableDict = ["name": "Picard", "rank": "captain"]

    • 通过 key 来访问,如果不存在对应的 key,则返回 nil

    let name2: String? = immutableDict["name"]

    • 更新 key 对应的 value

    mutableDict["name"] = "Janeway"

    • 添加新的 key-value

    mutableDict["ship"] = "Voyager"

    • 通过 key 来删除项目,如果 key 不存在,则返回 nil

    let rankWasRemoved: String? = mutableDict.removeValue(forKey: "rank")

    集合类型: Set

    • Set 会忽略重复项,所以 immutableSet 只有 2 项:"chocolate" 和 "vanilla"

    let immutableSet: Set = ["chocolate", "vanilla", "chocolate"]
    var mutableSet: Set = ["butterscotch", "strawberry"]

    • 测试包含关系

    immutableSet.contains("chocolate")

    • 添加项目

    mutableSet.insert("green tea")

    • 移除项目,如果没有找到项目,则返回 nil

    let flavorWasRemoved: String? = mutableSet.remove("strawberry")

    控制流:循环

    • 遍历一个列表或集合

    //for item in listOrSet {
    //    print(item)
    //}

    • 遍历字典

    //for (key, value) in dictionary {
    //    print("(key) = (value)")
    //}

    • 遍历范围

    // 闭区间操作符(...)
    for i in 0...10 {
      print(i) // 0 to 10
    }
    // 半开区间操作符(..<)
    for i in 0..<10 {
      print(i) // 0 to 9
    }

    • while

    var x = 0
    while x < 10 {
      x += 1
      print(x)
    }

    • repeat-while

    repeat {
      x -= 1
      print(x)
    } while(x > 0)

    控制流:条件语句

    • 使用 if 来选择不同路径

    let number = 88
    if (number <= 10) {
      // 如果 number <= 10, 则执行这里
    } else if (number > 10 && number < 100) {
      // 如果 number > 10 && number < 100, 则执行这里
    } else {
      // 否则执行这里
    }

    • 三元操作符

    // if-else条件的简写
    let height = 100
    let isTall = height > 200 ? true : false

    • 如果不满足一个或多个条件,请使用 guard 将程序控制权转移出一个范围

    for n in 1...30 {
      guard n % 2 == 0 else {
        continue
      }
      print("(n) is even")
    }

    • 使用 switch 来选择不同路径

    let year = 2012
    switch year {
    case 2003, 2004:
      // 如果 year 是 2003 或者 2004,则执行这个语句
      print("Panther or Tiger")
    case 2010:
      // 如果 year 的值是 2010,则执行这个语句
      print("Lion")
    case 2012...2015:
      // 如果 year 在 2012-2015 范围内(包含边界值),则执行这个语句
      print("Mountain Lion through El Captain")
    default: // 每个 switch 语句必须涵盖所有情况
      print("Not already classified")
    }

    函数

    • 返回 Void 的函数

    func sayHello() {
      print("Hello")
    }

    • 带参数的函数

    func sayHello(name: String) {
      print("Hello (name)!")
    }

    • 带默认参数值的函数

    //func sayHello(name: String = "Lorenzo") {
    //  print("Hello (name)!")
    //}

    • 混合默认值的参数和常规参数的函数

    //func sayHello(name: String = "Lorenzo", age: Int) {
    //  print("(name) is (age) years old!")
    //}
    //
    //sayHello(age: 35) // 只使用非默认值参数调用

    • 带参数和返回值的函数

    func add(x: Int, y: Int) -> Int {
      return x + y
    }
    let value = add(x: 8, y: 10)

    • 如果函数只有一个表达式,则可以省略 return

    func multiply(x: Int, y: Int) -> Int {
      x + y
    }

    • 指定参数的 label

    //func add(x xVal: Int, y yVal: Int) -> Int {
    //  return xVal + yVal
    //}

    • 省略一些参数的参数 label

    //func add(_ x: Int, y: Int) -> Int {
    //    return x + y
    //}
    //let value = add(8, y: 10)

    • 接受函数作为参数的函数

    func doMath(operation: (Int, Int) -> Int, a: Int, b: Int) -> Int {
      return operation(a, b)
    }

    闭包

    let adder: (Int, Int) -> Int = { (x, y) in x + y }

    • 带有速记参数名的闭包

    let square: (Int) -> Int = { $0 * $0 }

    • 将一个闭包传递给函数

    let addWithClosure = doMath(operation: adder, a: 2, b: 3)

    枚举

    enum Taste {
      case sweet, sour, salty, bitter, umami
    }
    let vinegarTaste = Taste.sour

    • 迭代枚举

    enum Food: CaseIterable {
      case pasta, pizza, hamburger
    }
    
    for food in Food.allCases {
      print(food)
    }

    • 带有 String 原始值的枚举

    enum Currency: String {
      case euro = "EUR"
      case dollar = "USD"
      case pound = "GBP"
    }

    • 打印原始值

    let euroSymbol = Currency.euro.rawValue
    print("The currency symbol for Euro is (euroSymbol)")

    • 带有关联值的枚举

    enum Content {
      case empty
      case text(String)
      case number(Int)
    }

    • 使用 switch 语句来匹配枚举值

    let content = Content.text("Hello")
    switch content {
    case .empty:
      print("Value is empty")
    case .text(let value): // 提取 String 值
      print("Value is (value)")
    case .number(_): // 忽略 Int 值
      print("Value is a number")
    }

    结构体

    struct User {
      var name: String
      var age: Int = 40
    }

    • 结构体自动创建一个逐一构造器,该构造器接收与所有属性匹配的参数

    let john = User(name: "John", age: 35)

    • 如果属性有初始值,逐一构造器会将其作为默认参数值

    let dave = User(name: "Dave")

    • 访问属性

    print("(john.name) is (john.age) years old")

    class Person {
      let name: String
      // 类构造器
      init(name: String) {
        self.name = name
      }
      
      // 使用 deinit 来执行对象资源清理操作
      deinit {
        print("Perform the deinitialization")
      }
      
      var numberOfLaughs: Int = 0
      func laugh() {
        numberOfLaughs += 1
      }
      
      // 定义一个计算属性
      var isHappy: Bool {
        return numberOfLaughs > 0
      }
    }
    
    let david = Person(name: "David")
    david.laugh()
    let happy = david.isHappy

    • 继承

    class Student: Person {
      var numberOfExams: Int = 0
      
      // 重写 isHappy 计算属性,以提供额外逻辑
      override var isHappy: Bool {
        numberOfLaughs > 0 && numberOfExams > 2
      }
    }
    
    let ray = Student(name: "Ray")
    ray.numberOfExams = 4
    ray.laugh()
    //let happy = ray.isHappy

    • 用 final 来标记 Child,以阻止其被继承

    final class Child: Person { }

    • 指定构造器和便捷构造器

    // 一个类需要至少一个指定构造器
    // 同时可以有一个或多个便捷构造器
    class ModeOfTransportation {
      let name: String
      // 定义一个指定构造器
      // 其携带一个名为 name 的参数
      init(name: String) {
        self.name = name
      }
      
      // 定义一个便捷构造器
      // 没有携带参数
      convenience init() {
        // 委托给内部指定构造器
        self.init(name: "Not classified")
      }
    }
    
    class Vehicle: ModeOfTransportation {
      let wheels: Int
      // 定义一个指定构造器
      // 带有两个参数
      init(name: String, wheels: Int) {
        self.wheels = wheels
        // 委托给父类指定构造器
        super.init(name: name)
      }
      
      // 重写父类便捷构造器
      override convenience init(name: String) {
        // 委托给内部指定构造器
        self.init(name: name, wheels: 4)
      }
    }

    扩展

    • 扩展可以给已存在的类、结构体、枚举或协议类型添加新的功能

    extension String {
      // 扩展 String 类型来计算一个 String 实例是真还是假
      var boolValue: Bool {
        if self == "1" {
          return true
        }
        return false
      }
    }
    
    let isTrue = "0".boolValue

    错误处理

    • 表示一个错误

    enum BeverageMachineError: Error {
      case invalidSelection
      case insufficientFunds
      case outOfStock
    }
    
    func selectBeverage(_ selection: Int) throws -> String {
      // Some logic here
      return "Waiting for beverage..."
    }

    • 如果在 do 代码块中抛出一个异常,它会与catch子句匹配,以确定其中哪一个可以处理错误

    let message: String
    do {
      message = try selectBeverage(20)
    } catch BeverageMachineError.invalidSelection {
      print("Invalid selection")
    } catch BeverageMachineError.insufficientFunds {
      print("Insufficient funds")
    } catch BeverageMachineError.outOfStock {
      print("Out of stock")
    } catch {
      print("Generic error")
    }

    • 如果在 try? 语句中抛出一个错误,则表达式的值为 nil

    let nillableMessage = try? selectBeverage(10)

    • 如果在 try! 抛出一个异常,则会导致运行时错误,否则获取返回值

    let throwableMessage = try! selectBeverage(10)

    访问控制

    • 一个模块(framework 或 application)一个独立的代码分发单元,可以在其它模块中通过 import 关键字来导入

    public class AccessLevelsShowcase { // 可以从其它模块中访问类
      public var somePublicProperty = 0 // 可以从其它模块中访问该属性
      var someInternalProperty = 0 // 可以在包含该类的块中访问该属性
      fileprivate func someFilePrivateMethod() {} // 可以从定义该类的源文件中访问该属性
      private func somePrivateMethod() {} // 可以在该类的代码块中访问该属性
    }

    协议

    import Foundation

    • Codable 与 Decodable 和 Encodable 两个协议的组合是一样的

    struct UserInfo: Codable {
      let username: String
      let loginCount: Int
    }

    • 实现 CustomStringConvertible 协议来提供将实例转换化字符串时的描述信息

    extension UserInfo: CustomStringConvertible {
      var description: String {
        return "(username) has tried to login (loginCount) time(s)"
      }
    }

    • 定义一个表达 JSON 的多行字符串

    let json = """
    { "username": "David", "loginCount": 2 }
    """

    • 使用 JSONDecoder 来序列化一个 JSON

    let decoder = JSONDecoder()
    // 将字符串转化为 UserInfo 实例
    let data = json.data(using: .utf8)!
    let userInfo = try! decoder.decode(UserInfo.self, from: data)
    print(userInfo)

    • 使用 Encodable 来序列化一个结构体

    let encoder = JSONEncoder()
    let userInfoData = try! encoder.encode(userInfo)
    // 将 UserInfo 实例转换为字符串表示
    let jsonString = String(data: userInfoData, encoding: .utf8)!
    print(jsonString)
  • 相关阅读:
    LinkedList源码浅析
    ArrayList/Vector/Stack底层分析
    遮罩层
    重写alert方法,去掉地址显示
    继承属性的函数
    为什么手机网页点击输入框的瞬间会出现灰色背景呢?怎么去掉灰色背景?
    伪类before和after
    五星好评
    String[]字符串数组,按字典顺序排列大小
    jquery ajax的load()方法和load()事件
  • 原文地址:https://www.cnblogs.com/strengthen/p/11928467.html
Copyright © 2011-2022 走看看