欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

巩固—Swift 4.0 基础知识(一)

程序员文章站 2024-02-20 16:43:28
...

元组

  • 定义: 可以将多个不同类型的值合成单个复合值。(可以是任意类型的)
  • 使用:
    • 可以将内容分为常量或变量进行常规访问:

       let https = (404,"Not Found") 
       let (statusCode, statusMessage) = https
       print("The status code is \(statusCode)") //输出:The status code is 404
      
    • 如只需某些元组的值,可以用“_”来忽略元组的部分值

       let (value , _ ) = https
       print("The status code is \(value)") //输出:The status code is 404
      
    • 使用从0开始索引访问元组各个元素值或给元组各个元素命名来访问

        let examples = (a:200,b:"OK")
        print("The value is \(examples.0)") //输出:The value is 200
        print("The value is \(examples.a)") //输出:The value is 200
      
    • 适用:

      • 作为函数的返回值特别有用
      • 互换值:(a,b)= (b,a) 等

可选类型

  • 定义:可能不存在值的数据类型。两种可能:要么是有一个值,你可以解开可选的访问值,或者是没有价值可言,为nil。
    • 注意: Object-C和swift中的nil不同:OC中是一个指向不存在对象的指针,只适用于对象(引用)类型,不适用与值类型。swift中nil不是一个指针,它是没有某种类型的值,任何类型的可选项都可以设置为nil,而不仅仅是对象类型。
  • 使用:
    • 如果你的代码中的常量或者变量在某些情况下缺少值时使用,则始终将其声明为适当类型的可选值。(可选类型默认值:nil)

    • 一般展开可选类型的写法

        if 可选类型名 != nil {
            print("It must have a value \(可选类型名!) ")
        } 
      
    • 安全展开可选类型的写法(可选绑定:来确定可选项是否包含值,如果是,则将值用作临时常量或变量。否则走else)

        if let newValue = 可选类型名 {
            print("It must have a value \(newValue) ")
        } 
        重点:可以包含多个(let newValue = 可选类型名),中间用“,”隔开,只要其中一个为nil则整个表达式都为否。
      
    • 可以使用感叹号来访问其基础值(注:一旦使用!访问,必须保证一定存在值,否则将error)

    • ??:进行解包,如果包含值则返回本身,否则返回默认值。a ?? b <==> a != nil ? a! : b

  • 隐式解析可选类型
    • 定义后缀!作为标准库中命名类型Optional<Wrapped>的语法糖,来实现自动解包的功能

        var implicitlyUnwrappedString: String!
        var explicitlyUnwrappedString: Optional<String>
      
    • 注意:由于隐式解包修改了包含器类型的声明语义,嵌套在元组类型或泛型的可选类型(比如字典元素类型或数组元素类型),不能被标记为隐式解包。

        let tupleOfImplicitlyUnwrappedElements: (Int!, Int!)  // 错误
        let implicitlyUnwrappedTuple: (Int, Int)!             // 正确
        
        let arrayOfImplicitlyUnwrappedElements: [Int!]        // 错误
        let implicitlyUnwrappedArray: [Int]!                  // 正确
      

元类型

  • 定义: 元类型是指类型的类型,包括类类型、结构体类型、枚举类型和协议类型。
  • 获取元类型:类、结构体或枚举类型的元类型是相应的类型名紧跟.Type。协议类型的元类型——并不是运行时符合该协议的具体类型——而是该协议名字紧跟.Protocol。比如,类SomeClass的元类型就是SomeClass.Type,协议SomeProtocol的元类型就是SomeProtocal.Protocol
  • 类型名.self来获取类型。也可以使用type(of:)来获取该实例在运行期的类型。

使用goard的正确姿势

  • 可以用goard:在验证入口条件时

      func refreshData() {
          let session = Int("12")
          goard let value = session else {reture}
          print("\(session!)")
      } 
      好处:
          1.一眼看出,这个条件检查并不是函数本身的功用,而是函数执行的先决条件。
          2.如果有人不小心将提前退出的语句从 else 表达式中移除了,编译器会及时告诉你这个错误。
    
  • 使用场景:方法中存在非常长的执行路径,在最终结果得到之前,中间会有多个需要被满足的条件,这些条件都应该为真,否则应该直接 return 或者抛出异常。(这些条件可以用guard抛出)

  • 可以用 guard:在可选值解包时(拍扁 if let..else 金字塔):使用 guard 的方式来解包可选值是非常推荐的。if let 的方式需要在大括号内使用解包之后的值,而 guard 语句将解包之后的值添加到了之后的作用域之中——所以你可以在使用 guard 解包之后直接使用它,不用包裹在大括号内。

       guard let id = json["id"] as? Int,
        let name = json["name"] as? String,
        let userId = json["user_id"] as? Int,
        let position = json["pos"] as? Double
      else {
          throw ParsingError.MissingData
      }
      return Task(id: id, name: name, userId: userId, position: position)
    

错误处理

  • 可以使用值得存在或不存在来传达函数的成功或失败,错误处理允许您确定故障的根本原因,如有必要,将错误传播到程序的一部分。

      如:throws关键字来引发错误
      func canThrowAnError() throws {
          
      }
      使用:当调用此函数时,需要使用如下方式,并加上try关键字,catch可以是多个
      do {
          try canThrowAnError()
      } catch {
      
      }
    

断言和前提条件

  • 定义:断言和前提条件是在运行时发生的检查。在执行任何其他代码之前,您可以使用它们确保满足基本条件。如果断言或前提条件中的布尔条件评估为true,则代码执行情况依然如常。如果条件求值false,程序的当前状态无效; 代码执行结束,您的应用程序已终止
  • 使用:
    • assert(age >= 0, "A person's age can't be less than zero."): 当条件为false就会抛出error错误信息,
    • precondition(index > 0, "Index must be greater than zero.") :同上
    • assertionFailure("A person's age can't be less than zero."):当已经检查了某条件时,可以直接吃用此方法抛出错误
    • preconditionFailure("A person's age can't be less than zero."):同上

基本运算符

  • a...b :全封闭区间,相当于[a,b];

  • a..<b: 半开半闭区间,相当于[a,b);

  • 单面范围: [a...],[...b],[..<b],

      for name in names[2...] { //从下标2开始到最后
          print(name)
      }
      for name in names[...2] { //从下标0到下标2的所有元素
          print(name)
      }
    

字符串与字符

  • 如果需要一个跨多行的字符串,请使用多行字符串文字 - 由三个双引号包围的一系列字符。

      如:let example = """
      The first row 
      
      The sencond Row 
      ...
      """
    
  • 使用”+“来拼接两个字符串。

      //实例
      let badStart = """
      one
      two
      """
      let end = """
      three
      """
      print(badStart + end)
      // Prints two lines:
      // one
      // twothree
       
      let goodStart = """
      one
      two
       
      """
      print(goodStart + end)
      // Prints three lines:
      // one
      // two
      // three
    
  • 可以使用”()“进行插入值。

  • 使用index(before:)and index(after:)方法访问给定索引之前和之后的索引String。要访问远离给定索引的索引,您可以使用该index(_:offsetBy:)方法,而不是多次调用其中一个方法。

      let greeting = "Guten Tag!"
      greeting[greeting.startIndex]
      // G
      greeting[greeting.index(before: greeting.endIndex)]
      // !
      greeting[greeting.index(after: greeting.startIndex)]
      // u
      let index = greeting.index(greeting.startIndex, offsetBy: 7)
      greeting[index]
      // a
      注意:endIndex是最后一个字符的下一个字符的索引,greeting[greeting.endIndex] // Error
    
  • 使用该indices属性访问字符串中单个字符的所有索引。

      for index in greeting.indices {
          print("\(greeting[index]) ", terminator: "")
      }
      // Prints "G u t e n   T a g ! "
      注意: terminator:关键字表示不换行。
    
  • 插入和删除(都是索引值,切记不是整数):

    • 要将单个字符插入到指定索引的字符串中,请使用该insert(_:at:)方法,并在指定的索引处插入另一个字符串的内容,然后使用该insert(contentsOf:at:)方法。
    • 要从指定索引的字符串中删除单个字符,请使用该remove(at:)方法,并删除指定范围内的子字符串,请使用以下removeSubrange(_:)方法:
  • 比较字符串: ”==“,(Swift中的字符串和字符比较不区分大小写。)

  • 前缀和后缀:要检查字符串是否具有特定的字符串前缀或后缀,请调用字符串hasPrefix("字符串")和 hasSuffix("字符串")方法

  • UTF-8、UTF-16和Unicode表示字符串

      for codeUnit in dogString.utf8 {
          print("\(codeUnit) ", terminator: "")
      }
      print("")
      // Prints "68 111 103 226 128 188 240 159 144 182 "
      
      for codeUnit in dogString.utf16 {
          print("\(codeUnit) ", terminator: "")
      }
      print("")
      // Prints "68 111 103 8252 55357 56374 "
      
      for scalar in dogString.unicodeScalars {
          print("\(scalar.value) ", terminator: "")
      }
      print("")
      // Prints "68 111 103 8252 128054 "
      for scalar in dogString.unicodeScalars {
          print("\(scalar) ", terminator: "")
      }
      //Prints "D o g !! "
    

集合类型

  • 数组遍历:
    定义:

      var someInts = [Int]()
      var threeDoubles = Array(repeating: 0.0, count: 3)
      // threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
      var shoppingList: [String] = ["Eggs", "Milk"]
      
      for (index, value) in shoppingList.enumerated() {
          print("Item \(index + 1): \(value)")
      }
      // Item 1: Six eggs
      // Item 2: Milk
      // Item 3: Flour
      // Item 4: Baking Powder
      // Item 5: Bananas
    
  • 集合:

  • 定义:

      var letters = Set<Character>()
      or
      var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
    
    • 使用该intersection(_:)方法创建一个仅具有两个集合通用值的新集合。
    • 使用该symmetricDifference(_:)方法创建一个新集合,其中的值可以是任一集,但不能同时使用。
    • 使用该union(_:)方法创建一个新集合,其中所有值都在两个集合中。
    • 使用该subtracting(_:)方法创建一个新集合,其值不在指定的集合中。
    • 使用“等于”运算符(==)来确定两个集合是否包含所有相同的值。
    • 使用该isSubset(of:)方法确定集合的所有值是否包含在指定的集合中。
    • 使用该isSuperset(of:)方法来确定集合是否包含指定集合中的所有值。
    • 使用isStrictSubset(of:)或isStrictSuperset(of:)方法来确定集合是子集还是超集,但不等于指定集。
    • 使用该isDisjoint(with:)方法来确定两个集合是否没有共同的值。
  • 字典:

  • 定义:

      var namesOfIntegers = [Int: String]()
      // namesOfIntegers is an empty [Int: String] dictionary
      var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
    
  • 遍历

      for (airportCode, airportName) in airports {
          print("\(airportCode): \(airportName)")
      }
      // YYZ: Toronto Pearson
      // LHR: London Heathrow
      
      等价于下面:
      for airportCode in airports.keys {
          print("Airport code: \(airportCode)")
      }
      // Airport code: YYZ
      // Airport code: LHR
       
      for airportName in airports.values {
          print("Airport name: \(airportName)")
      }
      // Airport name: Toronto Pearson
      // Airport name: London Heathrow
    
  • 新的遍历方式:

      使用该stride(from:to:by:)功能跳过不需要的标记。
      let minuteInterval = 5
      for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
          // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
      }
      
      也可以使用闭合范围stride(from:through:by:):
      let hours = 12
      let hourInterval = 3
      for tickMark in stride(from: 3, through: hours, by: hourInterval) {
          // render the tick mark every 3 hours (3, 6, 9, 12)
      }