【问题标题】:How to fix : "passing non-escaping parameter to function expecting @escaping closure"如何解决:“将非转义参数传递给期望 @escaping 闭包的函数”
【发布时间】:2017-04-12 05:00:04
【问题描述】:

我正在尝试将闭包用于一阶谓词演算,并且 我打算定义以下函数:

func ASSUM<U, V>(p: @escaping Pred<U>) -> (Pred<U>) -> Pred<(U, V)> {
    return { q in AND1(p: p, q: q) }
}

将谓词p: Pred&lt;U&gt; 作为参数,其中Pred&lt;U&gt;(T) -&gt; Bool 的类型别名:

typealias Pred<T> = (T) -> Bool

ASSUM 的返回是 (Pred&lt;U&gt;)-&gt;Pred&lt;(U,V)&gt; 类型的谓词转换器闭包。

但是编译器返回以下错误:

Passing non-escaping parameter 'q' to function expecting an @escaping closure

我了解定义的函数AND1 请求转义参数:

func AND1<U, V>(p: @escaping Pred<U>, q: @escaping Pred<V>) -> Pred<(U, V)> {
    return { (x, y) in (p(x) && q(y)) }
}

但我没有成功地在{ q in AND1(p: p, q: q) } 中明确地使q 转义。

我该如何解决这个问题?

【问题讨论】:

标签: swift generics escaping closures


【解决方案1】:

您必须将@escaping 属性显式添加到ASSUM 的返回类型闭包的参数中:

typealias Pred<T> = (T)->Bool

func AND1<U, V>(p: @escaping Pred<U> , q: @escaping Pred<V>) -> Pred<(U, V)> {
    return { (x,y) in (p(x) && q(y)) }
}

func ASSUM<U, V>(p: @escaping Pred<U>) -> (@escaping Pred<V>) -> Pred<(U, V)> { 
                                                       /* ^ note: I believe you 
                                                            want V here, not U  */
    return { AND1(p: p, q: $0) }
}

在返回的闭包中,q(匿名$0 参数)被正确推断为@escaping(并且不需要明确标记为@Hamish 指出的那样,谢谢!)。

还要注意ASSUM 中的泛型类型V 必须由调用者通过显式类型注释(或转换)推断,因为它不包含在@ 的任何参数中987654330@。

/* example usage */
let foo = { $0 < 2 }
let bar = { $0 != "bar" }

let fooAnd: (@escaping Pred<String>) -> Pred<(Int, String)> = ASSUM(p: foo)
let fooAndBar = fooAnd(bar)

print(fooAndBar((1, "foo"))) // true
print(fooAndBar((1, "bar"))) // false
print(fooAndBar((2, "foo"))) // false

最后,ALLCAPITAL 函数名称不符合 Swift 命名约定:您应该更喜欢 camelCase 命名(参见例如Swift API guidelines 了解更多详细信息)。

【讨论】:

  • 解决方案不是显式类型注释,而是在函数签名中将@escaping 添加到Pred&lt;V&gt; - 您可以随意从闭包中删除显式类型注释,并且让类型推断完成其余的工作:)
  • @dfri 感谢您的帮助和建议。我现在可以继续我的实验了。 (是的,你的权利,我将使用 camelCase 重写我的代码 ;-))
  • @Clause 乐于助人!
猜你喜欢
  • 2015-07-22
  • 2022-10-21
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 2010-10-18
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
相关资源
最近更新 更多