这是我在 Swift 中不理解的一件事
Posted
技术标签:
【中文标题】这是我在 Swift 中不理解的一件事【英文标题】:This is one thing I do not understand in Swift 【发布时间】:2019-07-01 20:01:33 【问题描述】:考虑以下几行:
我用这个创建了一个基于NSButton
的类:
typealias onClickHandler = (NSTextfieldSuper)->Void
var onClick: onClickHandler?
当用户点击该按钮的实例时,我会这样做:
if (self.onClick != nil)
onClick?(self)
我稍后在另一个班级中使用该按钮:
let button = SuperButton()
button.onClick = (textField: NSTextfieldSuper)->Void in
我不确定这是否是正确的语法。我想处理从父类的第一个闭包发送的按钮,该按钮是在其中创建的。
这是我能够在没有 Xcode 抱怨的情况下输入的唯一形式。如果这是正确的,那么->Void
的目的是什么?这可能会返回什么?
我只想处理发送的那个按钮。
顺便说一句,作为奖励,我必须用这个初始化几个按钮,所有按钮都运行相同的功能。做类似的事情会很好
func doSomething ()
然后
let button = SuperButton()
button.onClick = doSomething
有什么想法吗?
【问题讨论】:
【参考方案1】:这是我能够在没有 Xcode 抱怨的情况下输入的唯一形式。如果这是正确的,那么
->Void
的目的是什么?这可能会返回什么?
和你的typealias
一样,在 Swift 中函数类型的形式是:
(参数定义) -> 返回类型
并且不返回任何内容的函数的返回类型为Void
(类似于C)。闭包表达式的 full 形式是:
(
参数定义) ->
返回类型in
body
没有任何推论,此表达式提供了闭包的完整类型,并且您示例中的 -> Void
返回类型指定您的闭包不返回任何内容。在您的分配中,将在编译时检查此完整类型以符合 onClick
的类型。
现在 Swift 会推断出很多东西,并且有各种可用于闭包表达式的速记,你会发现 Swift 接受:
button.onClick = textField in
这里同时推断闭包的参数和返回类型。
顺便说一句,作为奖励,[...] 有什么想法吗?
只要使类型匹配:
func doSomething(textField : NSTextfieldSuper)
button.onClick = doSomething
与 (Objective-)C 中的不同,函数和闭包(C 中的块)是可互换的(因为它们在许多其他语言中,C 是这里的怪人)
HTH
【讨论】:
我明白了,但关于我问题的第一部分,我想我无法表达自己。我的意思是:闭包内部的(textField: NSTextfieldSuper)->Void
部分已经将变量textField
传递到闭包内部。 ->Void
部分的意义何在?没有意义?
这就像是说:拿这个返回void但返回textField的东西......(?)想象一下这不是void,而是Bool什么的。
我不确定我是否在关注你,但我在答案中添加了一些内容,这是否解决了你对-> Void
目的的担忧?
@SpaceDog - 最后一次尝试:编译器通常需要知道函数/闭包返回什么,以便可以为调用等生成正确的代码。返回值必须到达某个地方——堆栈上的机器寄存器,进入预分配的存储空间——这取决于返回类型并影响编译器必须生成的调用前和调用后代码。 Swift 中的Void
返回类型(写入或推断)告诉编译器调用不会返回任何内容,因此会生成正确的调用站点代码,并且函数/闭包主体中不应有return
。 HTH,关于这个的 O-O。
@SpaceDog - 闭包无效,因为它的(缺失的)主体不会评估为Bool
,但如果已修复,闭包本身将是有效的。但是,由于 LHS 和 RHS 类型不匹配,分配将无效。如果你问一个按钮处理程序是否可以返回一个值,答案是否定的——仅仅因为按钮的软件架构指定了一个不返回任何内容的处理程序,而不是因为 Swift 中的任何限制。这与您从 Obj-C 中了解的处理程序架构相同(在 Obj-C 中您提供的处理程序在 Obj-C-ese 中不返回任何内容)。以上是关于这是我在 Swift 中不理解的一件事的主要内容,如果未能解决你的问题,请参考以下文章