Swift 函數調用到底寫不寫參數名

來源:互聯網
上載者:User

標籤:ice   傳統   ima   play   tag   print   number   大於   alert   

最近真正開始學 Swift,在調用函數的時候遇到一個問題:到底寫不寫函數名?

我們來看兩個個例子:

// 1func test(a: Int, b: Int) ->Int {  return a + b}test(a: 1, b: 1) // (A)test(1, b:1) // (B)//2class Test {  var name: String  var age: Int  init(name: String, age: Int) {    self.name = name    self.age = age  }  func sayHello(word: String, place: String) {    println("Hello \(self.name), \(word) at \(place)")  }}var test = Test("Jack", age: 12) // (C)test.sayHello(word: "nice to meet you", place: "Beijing") // (D)

(A)(B)(C)(D)四處調用,哪個會報錯?













Playground




好吧,如果你還是直接翻到這裡,那我也無能為力了。

答案是:四處全部報錯。

正確的寫法是:

test(1, 1)var test = Test(name: "Jack", age: 12)test.sayHello("nice to meet you", place: "Beijing")

腳麻了嗎?麻了就對了,我跺我也麻。


我這智商基本告別 Swift 了到底咋回事

首先我們要清楚,Swift 中的調用有三種:

  • 函數調用(閉包也歸於函數,雖然所有函數本質上都是閉包。這句話看不懂的自動跳過,只是為了防人摳字眼)
  • 類初始化
  • 方法調用

如果沒有參數,那自然直接()調用,因此下面的討論前提是需要傳參,並且傳參數量大於一。

上一節的例子就是典型的三種調用,傳參的時候正確寫法如下:

<函數名>(參數值,參數值...) // 不加任何參數名,直接寫參數值<執行個體>.<方法名>(參數值,參數名:參數值,參數名:參數值...) // 方法調用第一個參數不寫參數名,後面的全部要寫。特殊情況是尾閉包,往下看<類初始化>(參數名:參數值,參數名:參數值...) // 類初始化所有參數都需要加參數名

單個函數的調用很好理解,其他語言裡也大多是這麼做的。我們主要解釋方法調用和類初始化這兩種調用。

為什麼 Swift 對方法調用和類初始化的參數名有如此奇怪的限制?主要原因是繼承 Objective-C 的一貫傳統。我們來看看 OC 裡面的寫法:

 [person setName:@"sam" andSecondName:@"job"]

setName是方法名,後面緊跟第一個參數,對應 Swift 中的寫法是:

person.setName("sam", andSecondName: "job")

也就是說,方法名中已經隱含了第一個參數的名字(雖然我們不知道第一個參數名是什麼,但是顯然第一個參數是Name,我們就可以知道第一個參數是名字),所以省略第一個參數名。

那麼init為什麼要加上第一個參數名?

直接看代碼:

[Test initWith:"Sam", andSecondName: "job"] // ocTest(name: "Sam", andSecondName: "job") / swift

由於 Swift 中初始化時候直接使用類名,沒有方法名,所以第一個參數名就不能省略了。

特殊情況

下面介紹幾種特殊情況。

尾閉包

首先是尾閉包。

Swift 中許多方法的最後一個參數是handler,我們可以傳入一個閉包。由於閉包寫到參數列表裡比較繁瑣,Swift 提供了一種新寫法:尾閉包。看例子:

alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) {  ......})

UIAlertAction的最後一個參數是handler,這裡用尾閉包來寫的話,就是在右括弧後面直接加閉包。當然,你也可以把閉包寫到參數列表裡,只是需要加參數名。

如果函數只需要handler一個參數,可以省略方法調用的圓括弧:

aaa.sort {  ...}
預設值

參數可以寫預設值,但是預設值有許多規矩:

  • 如果使用預設值,調用的時候,預設值對應的參數必須寫參數名。這裡影響的主要是函數和方法調用,因為類初始化本來就要寫全參數名。
  • 如果使用預設值並且預設值不是出現在最後,那調用的時候必須寫全所有參數。

綜合以上兩點,建議大家在使用預設值的時候,把帶預設值的參數放在列表結尾,這樣會方便許多。

強制指定參數名

如果你想強制要求調用時必須加參數名,可以在聲明的時候給參數加上外部參數名:

func test(outName name: String, outAge age: Int) {  ...}test(outName: "asd", outAge: 2)

這樣調用的時候必須加上對應的外部參數名。

如果外部參數名和內部參數名一樣,可以直接在參數名前加#

func test(#name: String, #age: Int) {  ...}test(outName: "asd", outAge: 2)
強製取消參數名

對於需要參數名的函數,你也可以在參數名前加_來強製取消參數名:

class Test {  func test(name: String, _ age: Int) {    ...  }}var test = Test()test.test("123", 3)
總之

Swift 中的函數調用真是個坑。

Swift 函數調用到底寫不寫參數名

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.