Swift 5.2

作者: Ian_ | 来源:发表于2020-10-14 11:22 被阅读0次

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

相关文章

网友评论

      本文标题:Swift 5.2

      本文链接:https://www.haomeiwen.com/subject/wwmduktx.html