swift之方法(Methods)

方法(Methods)


知识点:

1、方法的定义和使用;

2、方法的内部参数名和外部参数名;

3、类实例中的self说明;

4、变异(mutating)关键字;

5、类型方法实例;


方法是与某些特定类型相关联的函数。

结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。

实例方法 (Instance Methods)

实例方法是属于某个特定类、结构体或者枚举类型实例的方法。实例方法要写在它所属的类型的前后大括号之间。


例如:下面的例子,定义一个很简单的Counter类,Counter能被用来对一个动作发生的次数进行计数:

class Counter {
  var count = 0//可变属性count
  func increment() {
    ++count
  }
  func incrementBy(amount: Int) {
    count += amount
  }
  func reset() {
    count = 0
  }
}

调用:

 let counter = Counter()
 // 初始计数值是0
 counter.increment()
 // 计数值现在是1
 counter.incrementBy(5)
 // 计数值现在是6
 counter.reset()
 // 计数值现在是0

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

函数参数可以同时有一个局部名称(在函数体内部使用)和一个外部名称(在调用函数时使用)。

实例:

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

调用

let counter = Counter()
counter.incrementBy(5, numberOfTimes: 3)//这里要声明外部参数名才可以使用,好奇葩的感觉,因为在写代码的时候,如果你不加编译就会报错,不给你通过
// counter 的值现在是 15

解释:

你不必为第一个参数值再定义一个外部变量名:因为从函数名incrementBy(_numberOfTimes:)已经能很清楚地看出它的作用。但是第二个参数,就要被一个外部参数名称所限定,以便在方法被调用时明确它的作用。(这里我很想不明白,为什么还要一个外部参数名来修饰它,这不是默认第一个实参对应第一个行参的吗?何必多此一举呢???)


在每个类中,都有一个self属性。这个很好理解,你就当它是java中的this。就完了。

用处:在方法参数名和属性同名时使用。因为在方法中,参数名具有优先级高(因为近嘛)。所以需要额外指明。


swift允许动态修改实例的结构体和属性。要使用关键字 变异(mutating)来修饰方法。并且它做的任何改变在方法结束时还会保留在原始结构中。

要使用变异方法, 将关键字mutating 放到方法的func关键字之前就可以了:

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)//x,y初始值
somePoint.moveByX(2.0, y: 3.0)//加上初始值
print("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)//这里返回一个Point实例
  }
}
var somePoint = Point(x: 1.0, y: 1.0)//somePoint是self返回的的新的实例,同时初始化了x,y
somePoint.moveByX(2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// 打印输出: "The point is now at (3.0, 4.0)”

枚举的变异方法可以把self设置为相同的枚举类型中不同的成员:

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

上面的例子中定义了一个三态开关的枚举。每次调用next方法时,开关在不同的电源状态(OffLowHigh)之前循环切换。


这里又个很好的官方例子,慢慢走一遍程序,你就懂得了。这里是地址:swift中文学习地址

下面的例子定义了一个名为LevelTracker结构体。它监测玩家的游戏发展情况(游戏的不同层次或阶段)。这是一个单人游戏,但也可以存储多个玩家在同一设备上的游戏信息。

游戏初始时,所有的游戏等级(除了等级 1)都被锁定。每次有玩家完成一个等级,这个等级就对这个设备上的所有玩家解锁。LevelTracker结构体用静态属性和方法监测游戏的哪个等级已经被解锁。它还监测每个玩家的当前等级

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
        }
    }
}

下面,Player类使用LevelTracker来监测和更新每个玩家的发展进度:

class Player {
  var tracker = LevelTracker()
  let playerName: String
  func completedLevel(level: Int) {
    LevelTracker.unlockLevel(level + 1)
    tracker.advanceToLevel(level + 1)
  }
  init(name: String) {
    playerName = name
  }
}

调用
var player = Player(name: "Argyrios")
player.completedLevel(1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// 打印输出:highest unlocked level is now 2

如果你创建了第二个玩家,并尝试让他开始一个没有被任何玩家解锁的等级,那么这次设置玩家当前等级的尝试将会失败:

player = Player(name: "Beto")
if player.tracker.advanceToLevel(6) {
  print("player is now on level 6")
} else {
  print("level 6 has not yet been unlocked")
}
// 打印输出:level 6 has not yet been unlocked

以上大多是借鉴,加入了不少自己的理解和看法。
如有任何问题,请及时联系本人,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值