2016-02-05 54 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,并且在评估封闭时评估为正确的值。