Swift闭包符合typealias,包括Any

时间:2019-05-24 05:36:14

标签: swift

我有两个typealias声明

typealias QueryClosure = ((UInt?,UInt?)->([URLQueryItem])?)?
typealias SearchClosure = ((String?,UInt?)->([URLQueryItem])?)?

我为这些创建了闭包

var queryFunc: (QueryClosure)? = ( {a,b in
    return [URLQueryItem(name: "limit", value: "\(a ?? defaultPageSize)"), URLQueryItem(name: "offset", value: "\( (b ?? defaultPageIndex) * (a ?? defaultPageSize) )")]
})

var searchFunc: (SearchClosure)? = ( {query,b in
    return [URLQueryItem(name: "q", value: query), URLQueryItem(name: "page", value: "\(b ?? defaultPageIndex)")]
    }
)

现在,我既不想传递查询,也不想传递搜索闭包,我想传递普通闭包。

所以我创建了一个新的类型别名

typealias VariableClosure = ((Any?, Any?)->([URLQueryItem]))?

但是我无法转换为这种类型

let search : (VariableClosure) = ( {query,b in
    return [URLQueryItem(name: "q", value: query), URLQueryItem(name: "page", value: "\(b ?? defaultPageIndex)")]
    }
)

这给我的错误是

Cannot convert value of type '(String?, _) -> [URLQueryItem]' to specified type 'VariableClosure' (aka 'Optional<(Optional<Any>, Optional<Any>) -> Array<URLQueryItem>>')

如何创建一个符合typealias变量closure的闭包(或两个更好的闭包),或者以某种其他方式可以将闭包传递给我的通用类型别名。

1 个答案:

答案 0 :(得分:1)

由于URLQueryItem接受String,而您传递的query变量是Any类型,因此您必须首先typecast query使用之前将其复制到String

变量b也是如此。使用前,您必须typecastInt

let search: VariableClosure = {query,b in
    if let query = query as? Int, let b = b as? Int {
        return [URLQueryItem(name: "limit", value: "\(query ?? 10)"), URLQueryItem(name: "offset", value: "\( (b ?? 10) * (query ?? 10) )")]
    } else if let query = query as? String, let b = b as? Int {
        return [URLQueryItem(name: "q", value: query), URLQueryItem(name: "page", value: "\(b ?? 1)")]
    }
    return nil
}

在上述情况下,如果还期望其他类型的queryb,则必须手动处理它们。