1. Key Path
看下面代码, 都是在 Swift 5.2 新增的使用方式
let users = [User(email: "...", isAdmin: true), User(email: "...1", isAdmin: false)]
print(users.map(\.email))
print(users.filter(\.isAdmin))
var users1 = [User(email: "...11", isAdmin: true), nil]
let f1: (User?) -> User? = \User?.self
print(users1.compactMap(f1))
// print
["...", "...1"]
[__lldb_expr_58.User(email: "...", isAdmin: true)]
[__lldb_expr_58.User(email: "...11", isAdmin: true)]
问题1:
var users1 = [User(email: "...11", isAdmin: true), nil]
print(users1.compactMap(\.self))
// compiler error
Cannot convert value of type 'WritableKeyPath<_, _>' to expected argument type '(User?) throws -> ElementOfResult?'
这个问题是这样解释的:
The implementation is limited to key path literal expressions (for now), which means the following is not allowed:
let kp = \User.email // KeyPath<User, String>
users.map(kp)
// You write this:
let f: (User) -> String = \User.email
// The compiler generates something like this:
let f: (User) -> String = { kp in { root in root[keyPath: kp] } }(\User.email)
var nextIndex = 0
func makeIndex() -> Int {
defer {
print("do")
nextIndex += 1
}
return nextIndex
}
let getFirst: ([Int]) -> Int = \Array<Int>.[makeIndex()] // Calls makeIndex(), gets 0, forms \Array<Int>.[0]
let getSecond: ([Int]) -> Int = \Array<Int>.[makeIndex()] // Calls makeIndex(), gets 1, forms \Array<Int>.[1]
print(getFirst([5, 2, 3]))
print(nextIndex)
print(getSecond([5, 2, 3]))
print(nextIndex)
2. callAsFunction
简言之, a() 会帮你编译成 a.callAsFunction()
class AAA {
func callAsFunction() {
print("jjj")
}
func callAsFunction(a: Int) {
print("jjj \(a)")
}
}
let a = AAA()
a()
a(a: 10)
// print
jjj
jjj 10
和 @dynamicCallable 比较, 官方说 @dynamicCallable 对参数自定义提供了特殊的语法糖, 更猛一点.
@dynamicCallable
struct AAAA {
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Int {
for e in args {
print(e)
}
return args.map { $0.value }.reduce(0, +)
}
func dynamicallyCall(withArguments args: [Int]) -> Int {
return args.reduce(0, +)
}
}
let aa = AAAA()
print(aa(1, 2, 3))
print(aa(sd: 1, kk: 2, cc: 3))
// print
6
(key: "sd", value: 1)
(key: "kk", value: 2)
(key: "cc", value: 3)
6
网友评论