如何修复:“将非转义参数传递给期望@escaping闭包的函数”

时间:2016-11-28 12:53:48

标签: swift generics escaping closures

我正在尝试使用closurse进行First Order Predicate演算,以及 我打算定义以下函数:

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 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转义中明确制作{ q in AND1(p: p, q: q) }

我该如何解决这个问题?

1 个答案:

答案 0 :(得分: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(并且不需要明确标记为V,正如@Hamish所指出的那样, 谢谢!)。

另请注意,ASSUM中的通用类型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

最后,camelCase函数名称与Swift命名约定不一致:您应该更喜欢import dask.dataframe as dd dask_df = dd.from_pandas(pandasDataFrame, npartitions=2) dask_df = dask_df.groupby( ['one', 'two', 'three', 'four'], sort=False ).agg({'AGE' : lambda x: x * x }) 命名(请参阅例如Swift API guidelines以获取更多详细信息)。