swift基础笔记6-方法&下标脚本

摘要:类、结构体、枚举都可以定义实例方法;实例方法为给定类型的实例封装 了具体的任务与功能。类、结构体、枚举也可以定义类型方法;类型方法与类型本身相关联。类型方法与 Objecti ve-C 中的类方法(class methods)相似。
结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。在 Objective-C 中,类是唯一能定义 方法的类型。但在 Swift 中,你不仅能选择是否要定义一个类/结构体/枚举,还能灵活的在你创建的类型(类/结 构体/枚举)上定义方法。

实例方法

实例方法是属于某个特定类、结构体或者枚举类型实例的方法。具体说明略

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

Swift 中方法的名称通常用一个 介词指向方法的第一个参数,比如:  with,for ,by  等等。也就是说能通过方法名直接明白第一个参数的含义,所以Swift 默认仅给方法的第一个参数名称一个局部参数名称;默认同时给第二个和后续的参数名称局部参 数名称和外部参数名称。
例func incrementBy(amount: Int, numberOfTimes: Int),两个参数amount和numberOfTimes,默认情况下,Swift 只把amoun当作一个局部名称numberOfTimes看作局部名称又看作外部名称,方法名: incrementBy(_numberOfTimes:)已经能很清楚地 看出它的作用

修改方法的外部参数名称

有时为方法的第一个参数提供一个外部参数名称是非常有用的,尽管这不是默认的行为。你可以自己添加一个显 式的外部名称或者用一个井号( # )作为第一个参数的前缀来把这个局部名称当作外部名称使用。

在实例方法中修改值类型

结构体和枚举是值类型。一般情况下,值类型的属性不能在它的实例方法中被修改。
但是,如果你确实需要在某个具体的方法中修改结构体或者枚举的属性,你可以选择 变异(mutating) 这个方 法,然后方法就可以从方法内部改变它的属性;并且它做的任何改变在方法结束时还会保留在原始结构中。方法 还可以给它隐含的 self 属性赋值一个全新的实例,这个新实例在方法结束后将替换原来的实例。
例:

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)
print("The point is now at (\(somePoint.x), \(somePoint.y))") // 打印输出: "The point is now at (3.0, 4.0)"

上面的 Point 结构体定义了一个变异方法(mutating method) moveByX(_:y:) 用来移动点。 moveByX 方法 在被调用时修改了这个点,而不是返回一个新的点。方法定义时加上 mutating 关键字,这才让方法可以修改值 类型的属性。
注意:不能在结构体类型常量上调用变异方法,因为常量的属性不能被改变

在变异方法中给self赋值

变异方法能够赋给隐含属性 self 一个全新的实例。上面 Point 的例子可以用下面的方式改写:

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

类型方法(类方法)

定义类型本身调用的方法,这种方法就叫做类型方法。声明 结构体和枚举的类型方法,在方法的 func 关键字之前加上关键字 static 。类可能会用关键字 Class 来允许子类 重写父类的实现方法。
注意:在 Objective-C 里面,你只能为 Objective-C 的类定义类型方法(type-level methods)。在 Swift 中,你 可以为所有的类、结构体和枚举定义类型方法:每一个类型方法都被它所支持的类型显式包含。
例:
类的类型方法:

class SomeClass {
class func someTypeMethod() {
// type method implementation goes here }
} SomeClass.someTypeMethod()

下面是一个很有趣的例子,它定义了一个名为 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
} }
}

尽管我们没有使用类似 LevelTracker.highestUnlockedLeve l 的写法,这个类型方法还是能够访问静态属性 highestUnlockedLevel )
下面, 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
    }
}

下标脚本

下标脚本 可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问 集合(collection),列表(list)或序列(sequence的快捷方式,使用下标脚本的索引设置和获取值,不需要 再调用实例的特定的赋值和访问方法。
与定义实例方法类似,定义下标脚本使用 subscript 关键字,显式声明入参(一个 或多个)和返回类型。与实例方法不同的是下标脚本可以设定为读写或只读。这种方式又有点像计算型属性的get ter和setter:例

subscript(index: Int) -> Int {
 get {
    // 返回与入参匹配的Int类型的值 }
 set(newValue) { 
    // 执行赋值操作
    }
 }

与只读计算型属性一样,可以直接将原本应该写在 get 代码块中的代码写在 subscript 中:

subscript(index: Int) -> Int {
// 返回与入参匹配的Int类型的值
}

下面代码演示了一个在 TimesTable 结构体中使用只读下标脚本的用法,该结构体用来展示传入整数的n倍。

struct TimesTable {
let multiplier: Int subscript(index: Int) -> Int {
return multiplier * index }
}
let threeTimesTable = TimesTable(multiplier: 3) 
print("3的6倍是\(threeTimesTable[6])")
// 输出 "3的6倍是18"

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
 numberOfLegs["bird"] = 2
//在字典中添加了一个key为bird,值为2的数据

初学笔记,不喜勿喷,欢迎指点!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值