Methods
方法是一种属于某种类型的特殊函数。
类,枚举,结构体都可以定义一个方法。
实例方法
类,枚举,结构的实例才能调用的方法。
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by: 5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0
self属性
每一种类型的实例都有一个隐藏的类型self。
self指向当前引用自身,类似Java中的this。
上面的increment方法就可以调整为
func increment() {
self.count += 1
}
self 通常用来区分实例的属性和方法参数。
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.x > x
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
// Prints "This point is to the right of the line where x == 1.0"
在实例方法内修改值类型实例的属性
一般情况下,不能在实例方法内修改值类型实例的属性的,但是可以通过在实例方法前加关键字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)"
注意:不能对值类型实例的常量调用mutating 方法:
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// this will report an error
在mutting方法内给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)
}
}
在枚举中修改自身实例:
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
类型方法
类似Java中的静态方法。
实例方法只能通过类型的实例调用,而类型方法可以通过类型自身调用。
类型方法声明与类型属性声明类似。使用static关键字方法func关键字之前。
在类中,如果希望子类可以重新父类的类型方法,可以在func使用class关键字
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
static func someStaticTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()
在类型方法体内可以使用self来区分参数和类型属性,但使用self 只表示类型本身,而不是该类型的引用。
Subscripts
类,结构体和枚举都可以定义subscripts。subscripts是 collection, list, 或 sequence通过索引获取或设置数据的快捷方式。
- 一个类型可以定义多个subscripts
- subscripts可以有多个参数
Subscripts 语法
subscript(index: Int) -> Int {
get {
// return an appropriate subscript value here
}
set(newValue) {
// perform a suitable setting action here
}
}
类似属性的getter和setter方法,设置的subscript,去掉setter方法,省掉get关键字:
subscript(index: Int) -> Int {
// return an appropriate subscript value here
}
实现一个只读的subscript
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18"
定义一个可以使用subscript获取值和设置值的结构体Matrix
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValid(row: row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValid(row: row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
设置值
var matrix = Matrix(rows: 2, columns: 2)
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
获取值
let someValue = matrix[2, 2]
// this triggers an assert, because [2, 2] is outside of the matrix bounds