Xcode 8:函数类型不能让参数标签破坏我的构建

UKD*_*eek 72 ios completionhandler swift xcode8

似乎由于某种原因,Swift选择通过强制用户删除完成处理程序参数标签来使编码更难以读取.我已经阅读过Swift的讨论,仍然认为这是一个错误.至少他们可以让它成为可选的.

使用Xcode 8构建时 - 有没有办法强制编译器使用Swift 2.3,所以我不再会遇到这些错误?我已经更新了使用旧版Swift的选项(在构建设置下) xcode中的遗留支持 但我似乎仍然得到这个错误:

函数类型不能有参数标签'isloggedIn'; 请改用"_"

错误Xcode 8

如何在完成处理程序中保留标签?

Cra*_*lot 93

Swift设计者决定禁止函数类型的参数标签.

这里解释了推理:https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md

这是一个令人沮丧和可疑的选择,因为禁止参数标签使得更容易错误地调用闭包,这似乎比简化语言的类型系统更重要.

可用性>意识形态.

  • 仍然没有我在Swift 3.1中建议的解决方案的迹象 - 这里希望我们在swift 4之前得到它..讨厌这个改变太多!! (15认同)
  • 我同意这一点 - 但它不是一个真正的解决方案.我建议我们努力提出建议,以便可选择. (6认同)

sam*_*m-w 21

要考虑的解决方法.你做不到:

func doStuff(completion: (foo: Int, bar: String) -> Void) {
    ...
    completion(foo: 0, bar: "")
}
Run Code Online (Sandbox Code Playgroud)

......但你可以这样做:

func doStuff(completion: ((foo: Int, bar: String)) -> Void) {
    ...
    completion((foo: 0, bar: ""))
}
Run Code Online (Sandbox Code Playgroud)

即在你的闭包中有一个未命名的参数,在这种情况下是一个元组(foo: Int, bar: String).

它以自己的方式丑陋,但至少你保留了参数标签.

免责声明:我没有考虑过这种方法的捕获或性能影响.

  • 此解决方案的一个限制是元组不能具有单个值。 (2认同)

UKD*_*eek 10

根据上面的信息 - 似乎是真正解决这个问题的唯一方法,并确保其性能是提出一个提议,使参数标签可选,并提供以下视图:

  1. 提高开发速度(没有参数标签,它需要我们每次放入完成处理程序时向上滚动到方法的顶部.
  2. 减少错误:(由于不正确的完成处理程序条目,特别是那些期望布尔值的条目,我已经有几个错误)
  3. 使代码在团队成员中更具可读性.不是每个人都只有一个团队成员,因此能够轻松拿起其他人的代码是必须的.
  4. 最后,良好的编程实践意味着解决方案看起来应该与正在开发的实际项目一样. completionhandler: (newvalues, nil)看起来不像被管理的项目completionhandler(results: newValue, error:nil)

我希望阅读此内容的人在我提交之前分享他们对此的反馈/评论,以便我可以证明还有其他人支持这一点.

编辑:我已经在这里提交了网站:https: //lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161010/028083.html 似乎已经同意了.看起来它会发生,但讨论的是这是否作为Swift 4改进提交(极有可能)

  • 好吧,既然你要求它让我发泄:不会是第一次开源猴子搞砸了某些东西(在他们的宝贵贡献之前可用).阿门. (2认同)

Mic*_*son 9

您必须使用_来使您的参数未命名,这是不幸的.而不是在每个参数上添加_然后盲目地调用你的函数,我建议制作一个包装器对象.

由于丢失函数类型的命名参数会增加您使用错误值调用函数的风险,我建议将参数包装在结构中并使其成为函数的唯一参数.

这样,您的struct字段就会被命名,并且只有一种类型的值可以传递给您的函数.它比我们能够命名函数的参数更麻烦,但我们不能.至少这样你会更安全,你会感觉不那么脏.

struct LineNoteCellState {

    var lineNoteText: String?
    var printOnInvoice = false
    var printOnLabel = false
}
Run Code Online (Sandbox Code Playgroud)

以下是使用它的示例:

cell.configure(editCallback: { (_ state: LineNoteCellState) in

    self.lineNoteText = state.lineNoteText
    self.printOnInvoice = state.printOnInvoice
    self.printOnLabel = state.printOnLabel
})
Run Code Online (Sandbox Code Playgroud)


Mac*_*wic 6

半解决方法,注意_

completion: (_ success: Bool) -> Void
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说似乎没有自动完成 - 成功参数之前的下划线的功能是什么? (2认同)