2016-02-05 83 views
0

我是iOS編程的新手,我被困在SWIFT的閉包功能中。我已經提到了很多教程,並發現閉包是自編的代碼,可以用於許多方面,例如。作爲函數調用的參數,函數定義中的參數,變量。我在下面給出一個關於代碼&問題的相關想法。如果我的理解錯了,請幫助我。我知道我在很多方面都錯了,所以請糾正我。在Swift中關閉?

1.1st部分

func TEST(text1:String,text2:String,flag: (S1:String,S2:String)->Bool)//In this line,I think,I am using flag is a closure which is passed as parameter in a function. And if so why doesn't it follow the standard closure syntax? 
    { 
     if flag(S1: text1, S2: text2) == true//I want to check the return type what flag closure gets when it compares the both string during function call. Why can't I write as if flag == true as flag is the name of the closure and ultimately refers to the return type of the closure? 
     { 
      print("they are equal") 
     } 
     else 
     { 
      // 
     } 
    } 

第二部分

這部分是最麻煩的部分,真正讓我困惑時,我調用該函數。在這裏我也使用了相同的閉包。這裏發生了什麼?封口如何使用?它是捕捉價值還是其他東西?

TEST("heyy", text2: "heyy") { (S1, S2) -> Bool in 
    S1==S2 
} 

感謝您的關心。

回答

0

你的第一個功能是這樣工作的:

參數:

  • 串1
  • 字符串2
  • 採用兩個字符串作爲參數,並返回一個布爾
功能

body:

使用text1和text2執行函數(標誌)並檢查結果。 函數根本不知道你正在測試的是什麼,它只知道需要兩段文本,並且返回一個Bool。


所以這個函數允許你創建一個處理不同函數的一般方法,它們都有兩個字符串作爲輸入。您可以檢查是否相等,或者第一段文本是否是第二段文本的一部分等等。

這對很多事情都很有用,並且不像數組過濾/排序/映射如何工作。


第2部分:

這是你剛纔怎麼稱呼具有關閉功能。

TEST("heyy", text2: "heyy") { (S1, S2) -> Bool in 
    S1 == S2 
} 

您也可以這樣調用:

func testStringEqualityFor(text:String, and:String) -> Bool { 

    return text == and 

} 

TEST("hey", text2: "hey", flag: testStringEqualityFor) 

使用尾隨關閉語法來傳遞一個匿名函數相反的,你現在通過一個名爲功能的參數之一。


當你簡化它時,它會變得更清晰。

這是一個將另一個函數作爲參數的函數。 現在我們可以在裏面調用/使用這個函數。參數函數使用布爾作爲參數。所以我們給它一個true

func simpleFunctionWithClosure(closure:(success:Bool) -> Void) { 

    // use the closure 
    closure(success: true) 

} 

當我們使用,我們需要傳遞一個函數的函數。在Swift中,你有尾隨閉包的語法,但只有第一個函數可用(甚至可選)作爲參數。

尾隨封閉語法意味着強似命名功能,你可以寫:

myFunction { arguments-for-closure-as-tuple -> return-for-closure-as-tuple in 
    function-body 
} 

的關閉將收到的Bool參數並沒有返回如此Void

在身體中,我們可以處理參數,並與他們做東西。 但重要的是要記住閉包內部沒有直接調用。這是一個函數聲明將由simpleFunctionWithClosure

// use the function 
simpleFunctionWithClosure { (success) -> Void in 
    if success { 
     print("Yeah") 
    } else { 
     print("Ow") 
    } 
} 

或與某被指函數執行:

func argumentFunction(success:Bool) -> Void { 
    if success { 
     print("Yeah") 
    } else { 
     print("Ow") 
    } 
} 

simpleFunctionWithClosure(argumentFunction) 
+1

我正在寫一個答案,但決定在我投入更多時間之前閱讀你的答案。這是+1 –

0

編譯器不會有任何期待您如何關閉是。例如在第一種情況下,它無法估計關閉的進參數始終只是反映了測試功能的第一和第二個參數時,我們總是能夠寫出下面的代碼:

func Test(str1:String,str2:String,closure:(String,String)->Bool){ 
    if closure(str[str1.startIndex...str1.startIndex.advanced(2)],str2[str2.startIndex.advanced(1)...str2.endIndex]) 
    { ... }else{ ... } 
    //Just an example, everybody know no one write their code like this. 
} 

第二種情況,我還以爲你只是忽略了語法糖:

對於尾隨封閉A-> B:

{ a:A -> B in a.bValue() } 

等於:

{ a:A -> B in return a.bValue() } 

另外,我認爲這個TEST函數不是一個很好的例子,它的任務可以在不使用閉包的情況下完成。我想你可以自己編寫一個map函數,以便更好地理解爲什麼以及何時使用閉包。

1

您的封閉使用情況良好。閉包是一些可以傳遞到其他地方執行的代碼。在你的情況下,你可以選擇通過真正的測試你想要的功能TEST,簡單的字符串測試或不區分大小寫的測試等。這是閉包的第一個用法之一:獲得更多的通用性。

並且是閉包捕獲的東西,它捕獲環境的一部分,即它們被定義的環境。看:

var m = "foo" 
func test(text1:String, text2:String, testtFunc: (s1:String, s2:String) -> Bool) { 
    m = "bar" 
    if testFunc(s1: text1, s2: text2) { print("the test is true") } 
} 

m = "baz" 
test("heyy", text2: "heyy") { (s1, s2) -> Bool in 
    Swift.print("Value for m is \(m)") 
    return s1==s2 
} 

封閉捕獲m(即在在其中限定封閉的上下文中定義的變量),這是指該將打印bar因爲在執行關閉時,所捕獲的m等號到bar。評論bar -line和baz將被打印;評論baz -line和foo將被打印。封閉本身捕獲m,而不是其值,m,並且在評估封閉時評估爲正確的值。