解决方法 : "passing non-escaping parameter to function expecting @escaping closure"



我正在试验一阶谓词微积分的闭合用法,并且我打算定义以下功能:

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

以参数为谓词 p: Pred<U>,其中 Pred<U>(T) -> Bool的typealias:

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

ASSUM的返回是类型(Pred<U>)->Pred<(U,V)>的谓词变压器闭合。

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

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

我该如何修复?

您必须将@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必须通过呼叫者通过显式类型注释(或转换)来推断,因为它不包含在ASSUM的任何参数中。

/* 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指南有关的其他详细信息)。

相关内容

最新更新