Swift 方法

Swift 方法是與某些特定型別相關聯的函式

在 Objective-C 中,類是唯一能定義方法的型別。但在 Swift 中,你不僅能選擇是否要定義一個類/結構體/列舉,還能靈活的在你建立的型別(類/結構體/列舉)上定義方法。


例項方法

在 Swift 語言中,例項方法是屬於某個特定類、結構體或者列舉型別例項的方法。

例項方法提供以下方法:

  • 可以訪問和修改例項屬性

  • 提供與例項目的相關的功能

例項方法要寫在它所屬的型別的前後大括號({})之間。

例項方法能夠隱式訪問它所屬型別的所有的其他例項方法和屬性。

例項方法只能被它所屬的類的某個特定例項呼叫。

例項方法不能脫離於現存的例項而被呼叫。

語法

func funcname(Parameters) -> returntype
{
    Statement1
    Statement2
    ……
    Statement N
    return parameters
}

例項

import Cocoa

class Counter {
    var count = 0
    func increment() {
        count += 1
    }
    func incrementBy(amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}
// 初始計數值是0
let counter = Counter()

// 計數值現在是1
counter.increment()

// 計數值現在是6
counter.incrementBy(amount: 5)
print(counter.count)

// 計數值現在是0
counter.reset()
print(counter.count)

以上程式執行輸出結果為:

6
0

Counter類定義了三個例項方法:

  • increment 讓計數器按 1 遞增;
  • incrementBy(amount: Int) 讓計數器按一個指定的整數值遞增;
  • reset 將計數器重置為0。

Counter 這個類還聲明瞭一個可變屬性 count,用它來保持對當前計數器值的追蹤。


方法的區域性引數名稱和外部引數名稱

Swift 函式引數可以同時有一個區域性名稱(在函式體內部使用)和一個外部名稱(在呼叫函式時使用

Swift 中的方法和 Objective-C 中的方法極其相似。像在 Objective-C 中一樣,Swift 中方法的名稱通常用一個介詞指向方法的第一個引數,比如:with,for,by等等。

Swift 預設僅給方法的第一個引數名稱一個區域性引數名稱;默認同時給第二個和後續的引數名稱為全域性引數名稱。

以下例項中 'no1' 在swift中宣告為區域性引數名稱。'no2' 用於全域性的宣告並通過外部程式訪問。

import Cocoa

class division {
    var count: Int = 0
    func incrementBy(no1: Int, no2: Int) {
        count = no1 / no2
        print(count)
    }
}

let counter = division()
counter.incrementBy(no1: 1800, no2: 3)
counter.incrementBy(no1: 1600, no2: 5)
counter.incrementBy(no1: 11000, no2: 3)

以上程式執行輸出結果為:

600
320
3666

是否提供外部名稱設定

我們強制在第一個引數新增外部名稱把這個區域性名稱當作外部名稱使用(Swift 2.0前是使用 # 號)。

相反,我們呢也可以使用下劃線(_)設定第二個及後續的引數不提供一個外部名稱。

import Cocoa

class multiplication {
    var count: Int = 0
    func incrementBy(first no1: Int, no2: Int) {
        count = no1 * no2
        print(count)
    }
}

let counter = multiplication()
counter.incrementBy(first: 800, no2: 3)
counter.incrementBy(first: 100, no2: 5)
counter.incrementBy(first: 15000, no2: 3)

以上程式執行輸出結果為:

2400
500
45000

self 屬性

型別的每一個例項都有一個隱含屬性叫做self,self 完全等同於該例項本身。

你可以在一個例項的例項方法中使用這個隱含的self屬性來引用當前例項。

import Cocoa

class calculations {
    let a: Int
    let b: Int
    let res: Int
    
    init(a: Int, b: Int) {
        self.a = a
        self.b = b
        res = a + b
        print("Self 內: \(res)")
    }
    
    func tot(c: Int) -> Int {
        return res - c
    }
    
    func result() {
        print("結果為: \(tot(c: 20))")
        print("結果為: \(tot(c: 50))")
    }
}

let pri = calculations(a: 600, b: 300)
let sum = calculations(a: 1200, b: 300)

pri.result()
sum.result()

以上程式執行輸出結果為:

Self 內: 900
Self 內: 1500
結果為: 880
結果為: 850
結果為: 1480
結果為: 1450

在例項方法中修改值型別

Swift 語言中結構體和列舉是值型別。一般情況下,值型別的屬性不能在它的例項方法中被修改。

但是,如果你確實需要在某個具體的方法中修改結構體或者列舉的屬性,你可以選擇變異(mutating)這個方法,然後方法就可以從方法內部改變它的屬性;並且它做的任何改變在方法結束時還會保留在原始結構中。

方法還可以給它隱含的self屬性賦值一個全新的例項,這個新例項在方法結束後將替換原來的例項。

import Cocoa

struct area {
    var length = 1
    var breadth = 1
    
    func area() -> Int {
        return length * breadth
    }
    
    mutating func scaleBy(res: Int) {
        length *= res
        breadth *= res
        
        print(length)
        print(breadth)
    }
}

var val = area(length: 3, breadth: 5)
val.scaleBy(res: 3)
val.scaleBy(res: 30)
val.scaleBy(res: 300)

以上程式執行輸出結果為:

9
15
270
450
81000
135000

在可變方法中給 self 賦值

可變方法能夠賦給隱含屬性 self 一個全新的例項。

import Cocoa

struct area {
    var length = 1
    var breadth = 1
    
    func area() -> Int {
        return length * breadth
    }
    
    mutating func scaleBy(res: Int) {
        self.length *= res
        self.breadth *= res
        print(length)
        print(breadth)
    }
}
var val = area(length: 3, breadth: 5)
val.scaleBy(res: 13)

以上程式執行輸出結果為:

39
65

型別方法

例項方法是被型別的某個例項呼叫的方法,你也可以定義型別本身呼叫的方法,這種方法就叫做型別方法。

宣告結構體和列舉的型別方法,在方法的func關鍵字之前加上關鍵字static。類可能會用關鍵字class來允許子類重寫父類的實現方法。

型別方法和例項方法一樣用點號(.)語法呼叫。

import Cocoa

class Math
{
    class func abs(number: Int) -> Int
    {
        if number < 0
        {
            return (-number)
        }
        else
        {
            return number
        }
    }
}

struct absno
{
    static func abs(number: Int) -> Int
    {
        if number < 0
        {
            return (-number)
        }
        else
        {
            return number
        }
    }
}

let no = Math.abs(number: -35)
let num = absno.abs(number: -5)

print(no)
print(num)

以上程式執行輸出結果為:

35
5