【Swift學習】Swift編程之旅---方法(十五)

  在Swift中結構體和枚舉也可以定義方法,而在 Objective-C 中,類是惟一能定義方法的類型。函數

 

  實例方法spa

   實例方法是屬於某個特定類、結構體或者枚舉類型實例的方法,實例方法提供訪問和修改實例屬性的途徑,實例方法的語法與函數徹底一致。實例方法可以隱式訪問它所屬類型的全部的其餘實例方法和屬性。實例方法只能被它所屬的類的某個特定實例調用。實例方法不能脫離於現存的實例而被調用。code

class Counter { 
  var count = 0 
  func increment() { 
    count++ 
  } 
  func incrementBy(amount: Int) { 
    count += amount 
  } 
  func reset() { 
    count = 0 
  } 
} 

和調用屬性同樣,用點語法(dot syntax)調用實例方法blog

 

  方法的局部參數名稱和外部參數名稱rem

  Swift 默認僅給方法的第一個參數名稱一個局部參數名稱;默認同時給第二個和後續的參數名稱局部參數名稱和外部參數名稱。這個約定與典型的命名和調用約定相適應,與你在寫 Objective-C 的方法時很類似。這個約定還讓表達式方法在調用時不須要再限定參數名稱。it

下面Counter的另外寫法io

class Counter { 
  var count: Int = 0 
  func incrementBy(amount: Int, numberOfTimes: Int) { 
    count += amount * numberOfTimes 
  } 
} 

incrementBy方法有兩個參數: amount和numberOfTimes。默認狀況下,Swift 只把amount看成一個局部名稱,可是把numberOfTimes即看做局部名稱又看做外部名稱。下面調用這個方法:class

let counter = Counter() 
counter.incrementBy(5, numberOfTimes: 3) 
// counter value is now 15 
你沒必要爲第一個參數值再定義一個外部變量名:由於從函數名incrementBy已經能很清楚地看出它的做用。可是第二個參數,就要被一個外部參數名稱所限定,以便在方法被調用時明確它的做用。
 
這種默認的行爲可以有效的處理方法(method),相似於在參數numberOfTimes前寫一個井號(#):
func incrementBy(amount: Int, #numberOfTimes: Int) { 
 count += amount * numberOfTimes 
} 

 這種默認行爲使上面代碼意味着:在 Swift 中定義方法使用了與 Objective-C 一樣的語法風格,而且方法將以天然表達式的方式被調用。變量

 

  修改方法的外部參數名稱行爲循環

  你能夠本身添加一個顯式的外部名稱或者用一個井號(#)做爲第一個參數的前綴來把這個局部名稱看成外部名稱使用。
  相反,若是你不想爲方法的第二個及後續的參數提供一個外部名稱,能夠經過使用下劃線(_)做爲該參數的顯式外部名稱,這樣作將覆蓋默認行爲。

 

  self屬性

   類型的每個實例都有一個稱爲「self」的隱式屬性,它與實例自己至關。你能夠在一個實例的實例方法中使用這個隱含的self屬性來引用當前實例。

  上面例子中的increment方法還能夠這樣寫

func increment() { self.count++ } 

   你沒必要在你的代碼裏面常用self。Swift 假定你是指當前實例的屬性或者方法。這種假定在上面的Counter中已經示範了:Counter中的三個實例方法中都使用的是count(而不是self.count)

在實例方法的某個參數名稱與實例的某個屬性名稱相同的時候,優先參數名,因此在引用屬性時必須使用一種更嚴格的方式。這時你可使用self屬性來區分參數名稱和屬性名稱。下面的例子中,self消除方法參數x和實例屬性x之間的歧義:
struct Point { 
  var x = 0.0, y = 0.0 
  func isToTheRightOfX(x: Double) -> Bool { 
    return self.x > x 
  } 
} 
let somePoint = Point(x: 4.0, y: 5.0) 
if somePoint.isToTheRightOfX(1.0) { 
  println("This point is to the right of the line where x == 1.0") 
} 
// 輸出 "This point is to the right of the line where x == 1.0"(這個點在x等於1.0這條線的右邊)

 

 若是不使用self前綴,Swift 就認爲兩次使用的x都指的是名稱爲x的函數參數

 

  在實例方法中修改值類型

結構體和枚舉是值類型。通常狀況下,值類型的屬性不能在它的實例方法中被修改。可是,若是你確實須要在某個具體的方法中修改結構體或者枚舉的屬性,你能夠選擇mutating關鍵字修飾實例方法,而後方法就能夠從方法內部改變它的屬性;而且它作的任何改變在方法結束時還會保留在原始結構中。方法還能夠給它隱含的self屬性賦值一個全新的實例,這個新實例在方法結束後將替換原來的實例。將關鍵字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) 
somePoint.moveByX(2.0, y: 3.0) 
println("The point is now at (\(somePoint.x), \(somePoint.y))") 
// 輸出 "The point is now at (3.0, 4.0)"

 注意:不能在結構體類型常量上調用變異方法,由於常量的屬性不能被改變,即便想改變的是常量的變量屬性也不行,

 
   在變異方法中給self賦值(Assigning to self Within a Mutating Method)
 
  mutating方法可以賦給隱含屬性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) 
  } 
} 

 枚舉的變異方法能夠把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 如今等於 .High 
ovenLight.next() 
// ovenLight 如今等於 .Off 

 上面的例子中定義了一個三態開關的枚舉。每次調用next方法時,開關在不一樣的電源狀態(Off,Low,High)以前循環切換。

 
   類型方法
  聲明類的類型方法,在方法的func關鍵字以前加上關鍵字class;聲明結構體和枚舉的類型方法,在方法的func關鍵字以前加上關鍵字static。
注意:在 Objective-C 裏面,你只能爲 Objective-C 的類定義類型方法(type-level methods)。在 Swift 中,你能夠爲全部的類、結構體和枚舉定義類型方法:每個類型方法都被它所支持的類型顯式包含
 
  類型方法和實例方法同樣用點語法調用
class SomeClass { 
  class func someTypeMethod() { 
    // type method implementation goes here 
  } 
} 
SomeClass.someTypeMethod() 

 

  在類型方法的方法體(body)中,self指向這個類型自己,而不是類型的某個實例。對於結構體和枚舉來講,這意味着你能夠用self來消除靜態屬性和靜態方法參數之間的歧義
 
  通常來講,任何未限定的方法和屬性名稱,將會來自於本類中另外的類型級別的方法和屬性。一個類型方法能夠調用本類中另外一個類型方法的名稱,而無需在方法名稱前面加上類型名稱的前綴。一樣,結構體和枚舉的類型方法也可以直接經過靜態屬性的名稱訪問靜態屬性,而不須要類型名稱前綴。
相關文章
相關標籤/搜索