Swift从入门到精通第八篇 - 方法 初识

方法(学习笔记)

环境Xcode 11.0 beta4 swift 5.1

  • 方法
    • 结构体、枚举、类都可以定义方法(实例方法、类型方法)
  • 实例方法(Instance Methods)
    • 实例方法只能用实例来调用,不能单独使用

      class Counter {
          var count = 0
          func increment() {
              count += 1
          }
          func increment(by amount: Int) {
              count += amount
          }
          func reset() {
              count = 0
          }
      }
      let counter = Counter()
      // the initial counter value is 0
      counter.increment()
      // the counter's value is now 1
      counter.increment(by: 5)
      // the counter's value is now 6
      counter.reset()
      // the counter's value is now 0
    • self 属性,每个类型的实例都有的隐式的属性

      // 上面的increment()可写成如下形式
      func increment() {
          self.count += 1
      }
      // 如果方法的参数与实例相同时,就要显示的调用 self
      struct Point {
          var x = 0.0, y = 0.0
          func isToTheRightOf(x: Double) -> Bool {
              return self.x > x
          }
      }
      let somePoint = Point(x: 4.0, y: 5.0)
      if somePoint.isToTheRightOf(x: 1.0) {
          print("This point is to the right of the line where x == 1.0")
      }
      // Prints "This point is to the right of the line where x == 1.0"
    • 实例方法内修改值类型用 mutating 关键字修饰,该方法分配一个新的实例给隐藏的 self ,方法结束这个新的实例将会替换掉已经存在的实例

      // 枚举、结构体都是值类型
      struct Point {
          var x = 0.0, y = 0.0
          mutating func moveBy(x deltaX: Double, y deltaY: Double) {
              x += deltaX
              y += deltaY
          }
      }
      var somePoint = Point(x: 1.0, y: 1.0)
      somePoint.moveBy(x: 2.0, y: 3.0)
      print("The point is now at (\(somePoint.x), \(somePoint.y))")
      // Prints "The point is now at (3.0, 4.0)"
      // 不能用常量来调用 `mutating` 修饰的方法,因为常量不可修改
      let fixedPoint = Point(x: 3.0, y: 3.0)
      fixedPoint.moveBy(x: 2.0, y: 3.0)
      // this will report an error
    • 可变方法内给 self 赋值(Assigning to self Within a Mutating Method)

      // 上面的Point可以写成下面的形式
      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
              }
          }
      }
      var ovenLight = TriStateSwitch.low
      ovenLight.next()
      // ovenLight is now equal to .high
      ovenLight.next()
      // ovenLight is now equal to .off
  • 类型方法
    • func 前用关键字 static 或者 class (只能在类中使用,且子类可以重写父类的实现)修饰,类型方法中 self 指向类型本身

      class SomeClass {
          class func someTypeMethod() {
              // type method implementation goes here
          }
      }
      SomeClass.someTypeMethod()
      struct LevelTracker {
          static var highestUnlockedLevel = 1
          var currentLevel = 1
          //
          static func unlock(_ level: Int) {
              if level > highestUnlockedLevel { highestUnlockedLevel = level }
          }
          // 
          static func isUnlocked(_ level: Int) -> Bool {
              return level <= highestUnlockedLevel
          }
          // 
          @discardableResult
          mutating func advance(to level: Int) -> Bool {
              if LevelTracker.isUnlocked(level) {
                  currentLevel = level
                  return true
              } else {
                  return false
              }
          }
      }
      class Player {
          var tracker = LevelTracker()
          let playerName: String
          func complete(level: Int) {
              LevelTracker.unlock(level + 1)
              tracker.advance(to: level + 1)
          }
          init(name: String) {
              playerName = name
          }
      }
      var player = Player(name: "Argyrios")
      player.complete(level: 1)
      print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
      // Prints "highest unlocked level is now 2"
      // 创建一个新的player
      player = Player(name: "Beto")
      if player.tracker.advance(to: 6) {
          print("player is now on level 6")
      } else {
          print("level 6 has not yet been unlocked")
      }
      // Prints "level 6 has not yet been unlocked"

[Swift从入门到精通]