Swift lambda被插入到参数列表的末尾

Swift lambda被插入到参数列表的末尾,swift,Swift,使用Swift 3.1 func foo() { { () -> Void in print("oh, nice, now this works too!!!") }() } foo() 工作。。。但是 func foo() { print("Hi!") { () -> Void in print("oh, nice, now this works too!!!") }() } foo() 将导致 ERROR at

使用Swift 3.1

func foo() {
    { () ->  Void in 
    print("oh, nice, now this works too!!!")
    }()
}
foo()
工作。。。但是

func foo() {
    print("Hi!")
    { () ->  Void in 
    print("oh, nice, now this works too!!!")
    }()
}
foo()
将导致

ERROR at line 2, col 2: cannot invoke 'print' with an argument list
of type '(String, () -> Void)' 
这可以通过在打印后插入分号来修复

print("Hi!");

或lambda定义周围的括号。但是,我感兴趣的是,从Swift编译器的角度来看,这种行为的根本原因是什么?

在第二种情况下,需要将打印调用与lambda块分开

第一种情况:

func foo() { () -> () }
没问题,你想做什么就做什么

第二种情况:

编译器认为您在告诉print语句在闭包结束后执行闭包


因此,您需要用分号分隔print(“hi”)语句,或者将lambda块包装为显式的。

在第二种情况下,您需要将print调用与lambda块分隔开

第一种情况:

func foo() { () -> () }
没问题,你想做什么就做什么

第二种情况:

编译器认为您在告诉print语句在闭包结束后执行闭包


因此,您需要用分号分隔您的print(“hi”)语句,或者将lambda块包装为显式的。

尾部闭包语法不明确(非常确定某处有dupe)。尾部闭包语法不明确(非常确定某处有dupe)注意,同样让stament,例如让x=100,如果您使用print语句切换,将导致错误,您也必须使用分号。同样的问题。对于不需要类型为()->()的完成块的每个函数,都会出现崩溃/错误。您告诉编译器在初始化器完成其工作时执行lambda块,如init(value:Int,completion block:()->()){self.value=value completionBlock()},但在您的例子中,它是两个独立的语句。我希望它足够清楚:)如果你想做一些像让x=100{print(“hi”)}do var x=100{didSet{print(“hi:)”)}}哦,这很酷,就像func foo(){var x=100{didSet{print(x)}x=123456}->那么这就是计算属性语法了。func foo(){var x=100{didSet{print(x)}}print(x);x=10;x=12}将打印(100),然后打印10,然后打印12。您还可以在设置变量之前执行willSet运算符。设置变量后执行didSet。希望它能帮助您实现您想要的方式。请注意,同样让stament(例如,让x=100)也会导致错误。如果您使用print语句切换该语句,您也必须使用分号。同样的问题。对于不需要类型为()->()的完成块的每个函数,都会出现崩溃/错误。您告诉编译器在初始化器完成其工作时执行lambda块,如init(value:Int,completion block:()->()){self.value=value completionBlock()},但在您的例子中,它是两个独立的语句。我希望它足够清楚:)如果你想做一些像让x=100{print(“hi”)}do var x=100{didSet{print(“hi:)”)}}哦,这很酷,就像func foo(){var x=100{didSet{print(x)}x=123456}->那么这就是计算属性语法了。func foo(){var x=100{didSet{print(x)}}print(x);x=10;x=12}将打印(100),然后打印10,然后打印12。您还可以在设置变量之前执行willSet运算符。设置变量后执行didSet。希望它能以你想要的方式帮助你。