鞏固—Swift 5.0 基礎知識(二)

函數(shù)

定義:函數(shù)是執(zhí)行特定任務的自包含代碼塊忆蚀。(Swift中每個函數(shù)都有一個類型,由函數(shù)的參數(shù)類型和返回類型組成)姑裂。
使用:

  • 函數(shù)可以返回元組(也可以是可選元組:整個元組是可選的馋袜,而不僅僅是元組中的每個單獨的值)

      func minMax(array: [Int]) -> (min: Int, max: Int)? {
          if array.isEmpty { return nil }
          var currentMin = array[0]
          var currentMax = array[0]
          for value in array[1..<array.count] {
              if value < currentMin {
                  currentMin = value
              } else if value > currentMax {
                  currentMax = value
              }
          }
          return (currentMin, currentMax)
      }
    
  • 使用外部參數(shù)和內(nèi)部參數(shù),外部參數(shù)可以用“_”省略

      func greet(Person person: String, _ hometown: String) -> String {
          return "Hello \(person)!  Glad you could visit from \(hometown)."
      }
      print(greet(Person: "Bill", "Cupertino"))
      // Prints "Hello Bill!  Glad you could visit from Cupertino."
    
  • 使用默認參數(shù)值舶斧,調(diào)用該函數(shù)時可以省略該參數(shù)

       func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
          // If you omit the second argument when calling this function, then
          // the value of parameterWithDefault is 12 inside the function body.
      }
      someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault is 6
      someFunction(parameterWithoutDefault: 4) // parameterWithDefault is 12
    
  • 使用變量參數(shù)欣鳖,則此參數(shù)可以接受0-N的參數(shù)值,函數(shù)內(nèi)部茴厉,此參數(shù)當做函數(shù)處理泽台,關鍵字"..."(注:函數(shù)最多有一個可變參數(shù))

    func arithmeticMean(_ numbers: Double...) -> Double {
        var total: Double = 0
        for number in numbers {
            total += number
        }
        return total / Double(numbers.count)
    }
    arithmeticMean(1, 2, 3, 4, 5)
    // returns 3.0, which is the arithmetic mean of these five numbers
    arithmeticMean(3, 8.25, 18.75)
    // returns 10.0, which is the arithmetic mean of these three numbers
  • in-Out參數(shù)什荣,函數(shù)參數(shù)類型默認是let類型,不可更改怀酷,若需要更改參數(shù)稻爬,則在參數(shù)類型前加上關鍵字inout。(注意:in-Out參數(shù)不能具有默認值胰坟,并且可變參數(shù)不能標記為inout)

      func swapTwoInts(_ a: inout Int, _ b: inout Int) {
          (a,b) = (b,a) //交換兩個值
      }
      //調(diào)用方式如下:
      var someInt = 3
      var anotherInt = 107
      swapTwoInts(&someInt, &anotherInt)
      print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
      // Prints "someInt is now 107, and anotherInt is now 3"
    
  • 函數(shù)類型:函數(shù)參數(shù)類型和返回值類型的組合

      該函數(shù)的類型是(Int, Int) -> Int因篇,并返回Int泞辐。
      func addTwoInts(_ a: Int, _ b: Int) -> Int {
          return a + b
      }
      
      該函數(shù)的類型是() -> Void或“沒有參數(shù)的函數(shù)笔横,并返回” Void。
      func printHelloWorld() {
          print("hello, world")
      }
    
  • 函數(shù)類型可用作:函數(shù)參數(shù)類型咐吼,返回值類型等

  • 函數(shù)嵌套:可以在函數(shù)內(nèi)部定義其他函數(shù)

      //不推薦:一般一個函數(shù)就完成一個功能模塊
      func chooseStepFunction(backward: Bool) -> (Int) -> Int {
          func stepForward(input: Int) -> Int { return input + 1 }
          func stepBackward(input: Int) -> Int { return input - 1 }
          return backward ? stepBackward : stepForward
      }
    

閉包

  • 表達式一般形式

      {(參數(shù)) -> 返回類型 in
          聲明
      }
    
  • 幾種閉包的使用方式舉例:

      //完整格式:
      reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
          return s1 > s2
      })
      //省略參數(shù)類型:因為swift具有上下文自動推斷數(shù)據(jù)格式
      reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
      //閉包中只有一條語句時吹缔,稱為隱式返回,即省略return
      reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
      //最簡格式:使用參數(shù)值$0锯茄,$1厢塘,$2依次代替參數(shù)值
      reversedNames = names.sorted(by: { $0 > $1 } )
      //追尾閉包:既閉包類型作為函數(shù)參數(shù)的最后一個參數(shù)
      func someFunctionThatTakesAClosure(closure: () -> Void) {
          // function body goes here
      }
      調(diào)用時可以寫成如下格式:
      someFunctionThatTakesAClosure(closure: {
          // closure's body goes here
      })
    
    • 逃逸閉包:逃逸閉包恰恰與非逃逸閉包相反,其生命周期長于相關函數(shù)肌幽,當函數(shù)退出的時候晚碾,逃逸閉包的引用仍然被其他對象持有,不會在相關函數(shù)結(jié)束后釋放喂急。

    • 非逃逸閉包(默認):1. 把閉包作為參數(shù)傳遞給函數(shù)格嘁。2. 函數(shù)中運行該閉包。3. 退出函數(shù)廊移。

        class SomeClass {
            var x = 10
            func doSomething() {
                someFunctionWithEscapingClosure { self.x = 100 } //逃逸閉包(不能直接寫x)
                someFunctionWithNonescapingClosure { x = 200 } //非逃逸閉包(可以直接引用)
            }
        }
      
    • 自動閉包(@autoclosure):是一種自動創(chuàng)建的用來把作為實際參數(shù)傳遞給函數(shù)的表達式打包的閉包糕簿。

      • 要求:它不接受任何實際參數(shù)
      • 表現(xiàn):它被調(diào)用時,它會返回內(nèi)部打包的表達式的值
      • 好處:在于通過寫普通表達式代替顯式閉包而使你省略包圍函數(shù)形式參數(shù)的括號
      func testB()  {
         let neStr =  self.testbBlock1(block: "2sssssss")
       
         self.testBlock2(block: (print("ffjfjfjjf")))
       
         print(neStr)
      }
      
      func testbBlock1(block: @autoclosure ()->String) -> String {
         return block()
      }
      
      func testBlock2(block:@autoclosure ()->()) {
         block()
      }
      
      

枚舉

  • 枚舉語法

      enum 枚舉名 {
          case 枚舉值1
          case 枚舉值2
          ....
      }
      //注意: 1. 枚舉名應遵循首字母大寫的駝峰式復數(shù)命名
              2. 每個枚舉值沒有默認的0狡孔,1懂诗,2...等值
      //可以攜帶參數(shù)
      enum Barcode {
          case upc(Int, Int)
          case qrCode(String)
      }
      var productBarcode = Barcode.qrCode("ABCED")
      switch productBarcode {
          //如果所有關聯(lián)值被提取為常量或變量,則可以將var或let注釋放在枚舉值前面苗膝,如下:
          case let .upc(number1,number2) :
          print("\(number1)")
          case.qr(let code):
          print("\(code)")
      }
      //Prints:ABCED
    
  • 原始值:可以是字符串殃恒、字符、任意的整數(shù)或浮點數(shù)類型辱揭,但是原始值是唯一的芋类。

      enum Plant: Int {
          case mercury = 1,venus,earth
      }
      print("\(Plant.earth.rawValue)") == 3
    
  • 初始化值:如果你使用原始值定義枚舉,則枚舉將自動接收一個初始化器界阁。

      //possiblePlanet 為 venus
      let possiblePlanet = Planet(rawValue: 2)
    
  • 遞歸枚舉:簡單理解為自己調(diào)用自己侯繁,而遞歸枚舉并不是函數(shù),它并不執(zhí)行某項運算泡躯,他只是表達一個數(shù)據(jù)或者一種表達式贮竟。(關鍵字:indirect:表示可以遞歸)丽焊,整個enum都可以遞歸就在enum前加上關鍵字:indirect

      enum ArithmeticExpression {
          case number(Int)
          //indirect:為遞歸枚舉的關鍵字
          indirect case addition(ArithmeticExpression, ArithmeticExpression)
          indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
      }
      
      let five = ArithmeticExpression.number(5)
      let four = ArithmeticExpression.number(4)
      let sum = ArithmeticExpression.addition(five, four) //并沒有真正執(zhí)行運算
      let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
      
      實現(xiàn)遞歸枚舉的最好方式就是用遞歸函數(shù):
      func evaluate(_ expression: ArithmeticExpression) -> Int {
          switch expression {
          case let .number(value):
              return value
          case let .addition(left, right):
              return evaluate(left) + evaluate(right)
          case let .multiplication(left, right):
              return evaluate(left) * evaluate(right)
          }
      }
       
      print(evaluate(product))
      // Prints "18"
    

類和結(jié)構體

  • 相同點:
    • 定義屬性以存儲值
    • 定義提供功能的方法
    • 定義下標語法提供對其值得訪問
    • 定義初始化器以設置其默認實現(xiàn)
    • 擴展其功能
    • 遵守協(xié)議以提供某種特定的標準功能
  • 不同點:
    • 類可以被繼承
    • 類型轉(zhuǎn)換使您能夠在運行時檢查和解釋類實例的類型。
    • 取消初始化使類的實例可以釋放其分配的任何資源咕别。
    • 引用計數(shù)允許多個對類實例的引用技健。
  • 判斷是否是同類:(===)(!==)比較兩個類對象是否相等
  • 當結(jié)構體對象為let類型時,不管屬性是var或let都不能修改屬性的值惰拱,類則不同雌贱。能否修改由屬性的類型決定

屬性

  • 存儲屬性:是存儲在特定類或結(jié)構體實例里的一個常量或變量,只能用于類和結(jié)構體

      var firstValue: Int
      let secondValue: Int
    
  • 計算屬性:不直接存儲值偿短,而是提供一個getter和一個可選的setter方法欣孤,來間接和設置其他屬性或變量的值,可以用于類昔逗、結(jié)構體和枚舉

      struct AlternativeRect {
          var origin = Point()
          var size = Size()
          var center: Point { //計算屬性
              get { //只讀屬性時可以不寫get降传,直接返回
                  let centerX = origin.x + (size.width / 2)
                  let centerY = origin.y + (size.height / 2)
                  return Point(x: centerX, y: centerY)
              }
              set { //沒有set則為只讀計算屬性
                  origin.x = newValue.x - (size.width / 2)
                  origin.y = newValue.y - (size.height / 2)
              }
          }
      }
    
  • lazy屬性:指的是第一次被調(diào)用的時候才會計算其初始值的屬性。

    • 注意:lazy屬性必須聲明為變量var勾怒,因為屬性的初始值可能在實例構造完成之后才會得到婆排,而常量屬性在構造過程之前必須要有初始值。

    • 注意:如果一個被標記為lazy的屬性在沒有初始值時就同時被多個線程訪問笔链,則無法保證該屬性只會被初始化一次段只。

    • 格式

        lazy var 屬性名:屬性類型 = {調(diào)用一個沒有參數(shù),返回值是當前屬性類型的閉包鉴扫。
                                  閉包中需要創(chuàng)建一個當前屬性的變量返回}()
      
  • 類型屬性:無論創(chuàng)建多少個該類型的實例赞枕,這些屬性都是唯一共享的一份。(static關鍵字)

    • 注意:1. 必須給存儲類型屬性指定默認值幔妨,因為類型本身沒有構造器鹦赎。
      1. 存儲型類型屬性時演示初始化的,它們只有在第一次被訪問的時候才會被初始化误堡。即不需要lazy關鍵字修飾古话。
      1. 在類中可以使用class替代static來支持子類對父類的實現(xiàn)進行重寫。
      1. 類型屬性是通過類型本身來訪問锁施,而不是通過實例陪踩。

           class SomeClass {
               static var storedTypeProperty = "Some value."
               static var computedTypeProperty: Int {
                   return 27
               }
               class var overrideableComputedTypeProperty: Int {
                   return 107
               }
           }
        
  • 屬性觀察器:

    • willSet -- 在值被存儲之前被調(diào)用,可以再此名稱后加(變量名),默認參數(shù)是newValue,此值就代表將要賦的值悉抵。
    • didSet -- 在存儲值之前被調(diào)用肩狂,可以再此名稱后加(變量名),默認參數(shù)是oldValue,此值就代表原始值。

方法

  • 方法:實現(xiàn)一定功能的函數(shù)姥饰。類傻谁、結(jié)構體和枚舉中都能定義方法。

  • 注意:結(jié)構體和枚舉是值類型列粪。默認情況下审磁,不能從實例方法中修改值類型的屬性谈飒,若想要修改其屬性值,必須在方法func前添加mutating關鍵字态蒂。

      struct Point {
          var x = 0.0, y = 0.0
          mutating func moveBy(x deltaX: Double, y deltaY: Double) {
              x += deltaX
              y += deltaY
          }
      }
      等同于下面:
      struct Point {
          var x = 0.0, y = 0.0
          mutating func moveBy(x deltaX: Double, y deltaY: Double) {
              self = Point(x: x + deltaX, y: y + deltaY)
          }
      }
      //突變的方法
      enum TriStateSwitch {
          case off, low, high
          mutating func next() {
              switch self {
              case .off:
                  self = .low
              case .low:
                  self = .high
              case .high:
                  self = .off
              }
          }
      }
    
  • 類型方法和屬性方法

    • 類型屬性需要通過類型名來獲取杭措,通過變量或?qū)ο笕カ@取的話是找不到該屬性的
    • 類型屬性必須有初值,同時不能直接再構造函數(shù)中初始化钾恢,需要通過結(jié)構體名或類名去調(diào)用賦值
    • 類型方法——
      1. 在類中可以使用class關鍵字代替static
      2. 類型方法中不可以使用變量型屬性
      3. 類型方法中不可以調(diào)用變量型方法
      4. 變量型方法和類型方法可以同名
    • 總結(jié):變量和類型之間都不能互相調(diào)用
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末手素,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瘩蚪,更是在濱河造成了極大的恐慌泉懦,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件募舟,死亡現(xiàn)場離奇詭異祠斧,居然都是意外死亡闻察,警方通過查閱死者的電腦和手機拱礁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辕漂,“玉大人呢灶,你說我怎么就攤上這事《む冢” “怎么了鸯乃?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長跋涣。 經(jīng)常有香客問我缨睡,道長,這世上最難降的妖魔是什么陈辱? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任奖年,我火速辦了婚禮,結(jié)果婚禮上沛贪,老公的妹妹穿的比我還像新娘陋守。我一直安慰自己,他們只是感情好利赋,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布水评。 她就那樣靜靜地躺著,像睡著了一般媚送。 火紅的嫁衣襯著肌膚如雪中燥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天塘偎,我揣著相機與錄音疗涉,去河邊找鬼幽纷。 笑死,一個胖子當著我的面吹牛博敬,可吹牛的內(nèi)容都是我干的友浸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼偏窝,長吁一口氣:“原來是場噩夢啊……” “哼收恢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起祭往,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤伦意,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后硼补,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驮肉,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年已骇,在試婚紗的時候發(fā)現(xiàn)自己被綠了离钝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡褪储,死狀恐怖卵渴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鲤竹,我是刑警寧澤浪读,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站辛藻,受9級特大地震影響碘橘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吱肌,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一痘拆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岩榆,春花似錦错负、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至粒褒,卻和暖如春识颊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工祥款, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留清笨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓刃跛,卻偏偏與公主長得像抠艾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桨昙,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容