【问题标题】:Suppress Swift compiler warning禁止 Swift 编译器警告
【发布时间】:2015-03-15 15:00:52
【问题描述】:

我正在使用Nimble assertion framework 在 Swift(Xcode 6.3 beta)中进行单元测试。它工作正常,但编译器对 Nimble 源代码中的一行给出警告:

public func expect<T>(expression: () -> T?, file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> {
    return Expectation(
        expression: Expression(
            expression: expression,
            location: SourceLocation(file: file, line: line),
            isClosure: true))
}

警告是针对第一行的:

在带有默认参数的参数之前的闭包参数不会 被视为尾随闭包

这不是一个非常严重的问题,但我想在我的项目中将编译器警告的数量保持在较低水平(零)。有没有办法消除这个警告?

【问题讨论】:

    标签: ios swift closures compiler-warnings suppress-warnings


    【解决方案1】:

    如果方法签名如下所示,您可以避免警告:

    public func expect<T>(expression: (() -> T?), file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> 
    

    在第一个参数周围添加了额外的括号,使用 Swift 2.0 和 Xcode 7.1 进行了测试

    另一种解决方法是在闭包属性之前让所有属性都具有默认值,因为尾随闭包是一件非常方便的事情

    【讨论】:

    • Xcode 8:仍然有效!此外, () 在第一个默认参数之前绕过闭包。
    • 在 Xcode 8.2 中工作。但我想它是无证的,不是吗?
    【解决方案2】:

    @Julian Król 的回答是错误的,原因有两个:

    1. 代码 sn -p 演示了错误的语法,正确的是:

    public func expect&lt;T&gt;(expression: (() -&gt; T?), file: String = __FILE__, line: UInt = __LINE__) -&gt; Expectation&lt;T&gt;

    1. 即使在 Xcode 7.1 中使用正确的语法,它也不能解决问题,因为您不能使用尾随闭包调用此方法 - 它会给您带来类似 Missing argument for parameter #1 in call 的编译错误。

    使用提供的代码,您只会摆脱警告,但您在调用此函数时将无法使用尾随闭包。

    它修复了警告,因为在 Swift 中,只有一个孩子的元组可以与单个变量互换。甚至((((value)))) 也是the same 就像value。看起来编译器也无法将带有闭包子的元组识别为函数参数列表中的独立闭包。

    【讨论】:

    • 感谢您的纠正,我打错了,无论如何,如果列表中有任何具有默认值的属性,我会将闭包作为最后一个属性,以便能够使用尾随的东西。修正了我的答案,为好眼力点赞:)
    【解决方案3】:

    致该主题的所有未来读者:答案仅适用于尾随闭包的情况。 AFAIK,您无法像在 Objective-C 中那样抑制 Swift 警告(禁用特定行的警告),也许当 Swift 编译器的源代码将是开源时,会有一些有效的解决方案,而这个答案将会被更新。在此之前,您可以查看这些答案(不是 Swift 特定的):

    In Xcode, how to suppress all warnings in specific source files?

    Is there a way to suppress warnings in Xcode?

    如果可以更改expect的签名,则将参数表达式放在最后,如:

    public func expect<T>(file: String = __FILE__, line: UInt = __LINE__, expression: () -> T?) -> Expectation<T>
    

    说实话,将闭包参数作为第一个参数是很糟糕的设计。

    【讨论】:

    • 谢谢。我是 Swift 新手,我认为具有默认值的参数必须放在参数列表的末尾。
    • 我认为具有默认值的参数也应该位于列表的末尾。如果你有一个闭包和默认参数,这使得这个警告是不可避免的。
    • @SimplGy 我同意,但在这种情况下,您可以执行此解决方法。但是,在参数列表末尾添加默认值无疑是一种更好的样式。
    • 我认为您建议更改底层库?这不是解决方法。我想在我自己的代码中编写一个函数,它有一个闭包,然后是默认参数。有没有一种解决方法可以让我这样做?我认为我无法消除这个警告。
    • @DánielNagy 这是一种解决方法,我不确定我们是否应该将解决方法的答案标记为正确的答案。另外,我不确定我们是否应该推荐新开发人员分叉一个外部库来抑制编译器警告。我一直在搜索谷歌以抑制快速警告,这不是一件容易的事,具有讽刺意味的是,这篇文章排在大多数搜索之上,这令人沮丧,因为问题很明显,但答案是一个糟糕的解决方法 IMO .这充其量应该是一条评论。
    【解决方案4】:

    对我来说似乎是一个非常严重的警告,你绝对应该忽略它。看来你以为的带闭包参数的函数调用,其实是不带闭包参数的函数调用,后面跟着闭包。

    通过将闭包放入参数列表,或在调用之前将其分配给变量并传递该变量,您可以轻松避免警告并解决问题。

    【讨论】:

      猜你喜欢
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 2023-01-24
      相关资源
      最近更新 更多