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

元组

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

       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)
      }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容