Swift 学习笔记 「方法」

#Program

实例方法

class Counter {
  var count = 0
  func increment() {
    count++
  }
  func incrementBy(amount: Int) {
    count += amount
  }
  func reset() {
    count = 0
  }
}

方法的局部参数名和外部参数名

class Counter {
  var count: Int = 0
  func incrementBy(amount: Int, numberOfTimes: Int) {
    count += amount * numberOfTimes
  }
}

在 Swift 中,第一个参数拥有正常的局部参数名,而第二个参数和后面的参数则默认具有和局部参数名相同的外部参数名

self 属性

struct Point {
  var x = 0.0, y = 0.0
  func isToTheRightOfX(x: Double) -> Bool {
    return self.x > x
  }
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOfX(1.0) {
  println("This point is to the right of the line where x == 1.0")
}
// 输出 "This point is to the right of the line where x == 1.0"(这个点在x等于1.0这条线的右边)

可用来区分某个参数名和实例的某个属性名称相同的情况。

在实例方法中修改值类型

结构体和枚举是值类型,一般情况下,值类型的属性不能在它的实例方法中被修改

但,如果确实需要在某个方法中修改结构体或枚举的属性,可以在函数前加上 mutating 方法。

struct Point {
  var x = 0.0, y = 0.0
  mutating func moveByX(deltaX: Double, y deltaY: Double) {
    x += deltaX
    y += deltaY
  }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
println("The point is now at (\(somePoint.x), \(somePoint.y))")
// 输出 "The point is now at (3.0, 4.0)"

在变异方法中给 self 赋值

struct Point {
  var x = 0.0, y = 0.0
  mutating func moveByX(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 现在等于 .High
ovenLight.next()
// ovenLight 现在等于 .Off

类型方法

实例方法是被某个实例调用的方法,你也可以定义类型本身调用的方法,这种方法就叫做类型方法。

声明类的类型方法,在 func 关键字之前加上 class

声明结构体和枚举的类型方法,在 func 关键字之前加上 static

struct LevelTracker {
  static var highestUnlockedLevel = 1
  static func unlockLevel(level: Int) {
    if level > highestUnlockedLevel { highestUnlockedLevel = level }
  }
  static func levelIsUnlocked(level: Int) -> Bool {
    return level <= highestUnlockedLevel
  }
  var currentLevel = 1
  mutating func advanceToLevel(level: Int) -> Bool {
    if LevelTracker.levelIsUnlocked(level) {
      currentLevel = level
      return true
    } else {
      return false
    }
  }
}

END