Ios 斯威夫特?

Ios 斯威夫特?,ios,swift,closures,Ios,Swift,Closures,我不熟悉iOS编码,我被SWIFT的闭包功能困住了。我参考了很多教程,发现闭包是自写的代码,可以在很多方面使用,例如函数调用中的参数、函数定义中的参数、变量。我在下面给出一个例子,以及我对代码和问题的相关想法。如果我理解错误,请帮助我。我知道我在很多方面都错了,所以请纠正我 1.1部分 func TEST(text1:String,text2:String,flag: (S1:String,S2:String)->Bool)//In this line,I think,I am usin

我不熟悉iOS编码,我被SWIFT的闭包功能困住了。我参考了很多教程,发现闭包是自写的代码,可以在很多方面使用,例如函数调用中的参数、函数定义中的参数、变量。我在下面给出一个例子,以及我对代码和问题的相关想法。如果我理解错误,请帮助我。我知道我在很多方面都错了,所以请纠正我

1.1部分

 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
}

感谢您的关照。

您的第一个函数是这样工作的:

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

    return text == and

}

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

  • 字符串1
  • 字符串2
  • 以两个字符串作为参数并返回布尔值的函数
正文:

使用text1和text2执行函数(标志),并检查结果。 该函数根本不知道您正在测试什么,它只知道需要两段文本,并且将返回一个Bool


因此,这个函数允许您创建一种处理不同函数的通用方法,这些函数都有两个字符串作为输入。您可以检查是否相等,或者第一段文本是否是第二段文本的一部分,依此类推

这对很多事情都很有用,与数组过滤/排序/映射的工作原理相差不远


第二部分:

这就是使用闭包调用函数的方式

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)
现在,不再使用尾部闭包语法传递未命名函数,而是将命名函数作为参数之一传递


当你简化它时,它会变得更清晰

这是一个将另一个函数作为参数的函数。 现在我们可以在其中调用/使用此函数。argument函数接受bool作为其参数。所以我们给它一个
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

在身体里,我们可以处理这些论点并处理它们。 但重要的是要记住,闭包中的内容不是直接调用的。它是一个函数声明,将由
SimpleFunctionWithClose

// 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)

编译器不会对闭包的用途有任何期望。例如,在第一种情况下,当我们始终能够编写以下代码时,它无法估计闭包的入口参数始终只是反映到测试函数的第一个和第二个参数:

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() }

另外,我认为这个测试函数不是一个很好的例子,因为它的任务不用闭包就可以完成。我认为您可以自己编写一个映射函数,以便更好地理解为什么以及何时使用闭包。

您的闭包用法还可以。闭包是一些可以传递到其他地方执行的代码。在您的情况下,您可以选择通过真正的测试,如函数
测试
、简单字符串测试或不区分大小写测试等。这是闭包的第一个用法:获得更多泛型

是的,闭包捕获了一些东西,它捕获了环境的某些部分,即定义它们的上下文。看:

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
-将打印行和
baz
;注释
baz
-将打印第行和
foo
。闭包捕获的是
m
,而不是它本身的值,
m
,当闭包被评估时,它被评估为正确的值。

我正在写一个答案,但决定在投入更多时间之前阅读你的答案。这是现场+1