Swift3.0P1 语法指南——方法
1、方法
方法是和特定类型关联的函数。类、结构体和枚举都能定义实例方法(instance methods),也能定义类型方法( type methods)。
2、实例方法(Instance Methods)
实例方法属于类、结构体或枚举的实例,它们提供实例的功能实现,或者是访问和修改属性的值,或者是提供实例目的相关的功能。
实例方法的语法和函数一样。
实例方法只能被它所属的类的某个实例调用。实例方法不能脱离于现存的实例而被调用。
 class Counter {
     var count =
     func increment() {
         count += 1     }
     func increment(by amount: Int) {
         count += amount
     }
     func reset() {
         count =
     }
 }
实例方法的调用与属性相同:
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by:)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0
3、self属性
每一个类型的实例都有一个隐式的属性self,self完全等同于实例本身。
可以在实例的方法中用self作为实例本身的引用。
1 func increment() {
2     self.count += 1
3 }
实际上,不必显式地写self。如果你在方法中使用已知的属性或方法时不显式地写self,Swift会认为你使用的是当前实例的属性或方法。因此,在上述方法中可以用count而不是self.count。
当方法的参数名和实例的属性同名时,这种规则会导致异常。这种情况下,就有必要使用self来区分参数名和属性名。
 1 struct Point {
 2     var x = 0.0, y = 0.0
 3     func isToTheRightOfX(x: Double) -> Bool {
 4         return self.x > x
 5     }
 6 }
 7 let somePoint = Point(x: 4.0, y: 5.0)
 8 if somePoint.isToTheRightOfX(1.0) {
 9     print("This point is to the right of the line where x == 1.0")
10 }
11 // prints "This point is to the right of the line where x == 1.0"
4、在实例方法中修改值类型(Value Types)
结构体和枚举都是值类型,默认情况下,值类型属性不能在实例方法中修改。
然而,如果你需要在实例方法中修改结构体或枚举属性,你可以选择将这个方法变异(mutating),这样,就可以在方法内部修改属性,并且任何改变都会在方法结束后保留在原始结构体中。这种方法也可以将一个新的实例赋值给self属性,方法结束后,这个新的实例会替换旧的实例。
方法定义时加上mutating关键字,这才让方法可以修改值类型的属性:
 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)"
注意:不能在结构体类型常量上调用变异方法,因为常量的属性不能被改变,即使想改变的是常量的变量属性也不行。
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0)
// this will report an error
5、在mutating方法中赋值self
 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)
     }
 }
上述的变异方法moveBy(x:y:)创建了一个新的结构(它的 x 和 y 的值都被设定为目标值)。它的效果与之前的是一致的。
枚举的变异方法可以把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 is now equal to .High
 ovenLight.next()
 // ovenLight is now equal to .Off
6、类型方法( Type Methods)
实例方法是被类型的某个实例调用的方法。你也可以定义类型本身调用的方法,称为类型方法。
声明结构体和枚举的类型方法,在方法的func关键字之前加上关键字static。类可以用关键字class来允许子类重写父类的实现方法。
类型方法的调用:
 class SomeClass {
     class func someTypeMethod() {
         // type method implementation goes here
     }
 }
 SomeClass.someTypeMethod()
类型方法中的self等价于类型本身,而不是等价于类型实例。对于结构体和枚举而言,你可以用self来区分类型属性和类型方法参数。
一般来说,在类方法中,任何没有用self限定的方法和属性名称,将会来自于本类中其他的类型级别的方法和属性。类型方法可以直接用其他类型方法的名字来调用它们,不必加上类型名。类似地,枚举和结构体的类型属性里也可以直接用其他类型属性的名字来访问。
下面的例子定义了一个名为LevelTracker结构体。它监测玩家的游戏发展情况(游戏的不同阶段)。这是一个单人游戏,但也可以存储多个玩家在同一设备上的游戏信息。
游戏初始时,所有的游戏等级(除了等级 1)都被锁定。每次有玩家完成一个等级,这个等级就对这个设备上的所有玩家解锁。LevelTracker结构体用静态属性和方法监测游戏的哪个等级已经被解锁。它还监测每个玩家的当前等级。
 struct LevelTracker {
     static var highestUnlockedLevel =
     var currentLevel = 
     static func unlock(_ level: Int) {
         if level > highestUnlockedLevel { highestUnlockedLevel = level }
     }
     static func isUnlocked(_ level: Int) -> Bool {
         return level <= highestUnlockedLevel
11    }
     @discardableResult
     mutating func advance(to level: Int) -> Bool {
         if LevelTracker.isUnlocked(level) {
             currentLevel = level
             return true
         } else {
             return false
         }
     }
 }
LevelTracker监测玩家的已解锁的最高等级。这个值被存储在类型属性highestUnlockedLevel中。
LevelTracker还定义了两个类型方法与highestUnlockedLevel配合工作。
第一个类型方法是unlock:一旦新等级被解锁,它会更新highestUnlockedLevel的值。
第二个类型方法是isUnlocked:如果某个给定的等级已经被解锁,它将返回true。(注意:尽管我们没有使用类似LevelTracker.highestUnlockedLevel的写法,这个类型方法还是能够访问类型属性highestUnlockedLevel)
除了类型属性和类型方法,LevelTracker还监测每个玩家的进度。它用实例属性currentLevel来监测玩家当前的等级。
为了便于管理currentLevel属性,LevelTracker定义了实例方法advance(to:)。这个方法会在更新currentLevel之前检查所请求的新等级是否已经解锁。advance(to:)方法返回布尔值以指示是否能够设置currentLevel。用@discardableResult指示调用advance(to:)方法时可以忽略返回值。
下面,来使用这个结构体:
 class Player {
     var tracker = LevelTracker()
     let playerName: String
     func complete(level: Int) {
         LevelTracker.unlock(level + )
         tracker.advance(to:level + )
     }
     init(name: String) {
         playerName = name
     }
 }
Player类创建一个新的LevelTracker实例来监测这个用户的进度。它提供了complet方法:一旦玩家完成某个指定等级就调用它。这个方法为所有玩家解锁下一等级,并且将当前玩家的进度更新为下一等级。(我们忽略了advance(to:).返回的布尔值,因为之前调用LevelTracker.unlockLevel时就知道了这个等级已经被解锁了)。
你还可以为一个新的玩家创建一个Player的实例,让玩家完成等级一:
var player = Player(name: "Argyrios")
player.complete(level: )
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// prints "highest unlocked level is now 2"
如果你创建了第二个玩家,并尝试让他开始一个没有被任何玩家解锁的等级,那么这次设置玩家当前等级的尝试将会失败:
player = Player(name: "Beto")
if player.tracker.advance(to:) {
print("player is now on level 6")
} else {
print("level 6 has not yet been unlocked")
}
// 打印输出:level 6 has not yet been unlocked
Swift3.0P1 语法指南——方法的更多相关文章
- Swift3.0P1 语法指南——构造器
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——下标
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——属性
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——类和结构体
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——枚举
		
原档: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programm ...
 - Swift3.0P1 语法指南——闭包
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——继承
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——函数
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 - Swift3.0P1 语法指南——控制流
		
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
 
随机推荐
- 骨骼蒙皮动画算法(Linear Blending Skinning)
			
交互式变形是编辑几何模型的重要手段,目前出现了许多实时.直观的交互式变形方法.本文介绍一种利用线性混合蒙皮(Linear Blending Skinning,LBS)技术来实现网格变形的方法,线性混合 ...
 - BZOJ 3524: [Poi2014]Couriers [主席树]
			
3524: [Poi2014]Couriers Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1892 Solved: 683[Submit][St ...
 - Google Material Design的图标字体使用教程
			
使用教程 1. 打开Material icons下载页 2. 选择要下载的图标 (目前不能多选>_<) 3.选择要下载的格式即可 图标字体使用教程 [方法一] STEP 1: 引入字体文件 ...
 - [zz]如何在C语言程序中处理汉字
			
学习过C语言的人也许有时会遇到这样一个问题:如何用变量存储汉字以及对这些变量进行操作.目前许多C语言参考书中都没涉及到这个问题,程序中多为处理英文变量和英文字符串,涉及到汉字的情况也大都是在print ...
 - jdbc执行Statement接口的步骤
			
jdbc执行Statement接口的步骤如下: 1)驱动注册程序: Class.forName(com.mysql.jdbc.Driver); 2)获取连接对象: Connection conn = ...
 - java多线程系类:JUC线程池:03之线程池原理(二)(转)
			
概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...
 - codevs 2894 保留小数
			
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 给你一个实数,小数点后不超过50位,请你保留到小数点后n位(四舍五入!!!) 输 ...
 - 14-前端开发之CSS
			
什么是 CSS ? CSS 指层叠样式表 (Cascading Style Sheets),用于对页面进行美化. 存在的方式有3种: 元素内联:在标签中使用 style='xx:xxx;' 页面嵌入: ...
 - 2016-2017-2 《Java程序设计》预备作业1 总结
			
2016-2017-2 <Java程序设计>预备作业1 总结 预备作业01:你期望的师生关系是什么见https://edu.cnblogs.com/campus/besti/2016-20 ...
 - 5G为何采纳华为力挺的Polar码?一个通信工程师的大实话
			
Polar码被采纳为5G eMBB场景的控制信道编码,这两天连续被这条消息刷屏,连吃瓜群众都直呼好爽. 然而,随着媒体报道的持续发酵,真相在口口相传中变了形,不乏夸大不实之嫌,小编终于坐不住了,也想吐 ...