swift之方法(Methods)

来源:互联网 发布:保益软件 编辑:程序博客网 时间:2024/05/17 23:28

方法(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,ysomePoint.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.LowovenLight.next()// ovenLight 现在等于 .HighovenLight.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

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

0 0