## @dynamicMemberLookup #### 介绍 Swift 4.2 中引入了一个新的语法`@dynamicMemberLookup`/uff08动态成员查找/uff09。使用`@dynamicMemberLookup`标记了目标/uff08类、结构体、枚举、协议/uff09/uff0c实现`subscript(dynamicMember member: String) `方法后我们就可以访问到对象不存在的属性。 #### 核心内容 - `@dynamicMemberLookup`/uff1a标记类、结构体、枚举、协议 - `subscript(dynamicMember member: String) `/uff1a实现该方法/uff0c可以像数组和字典一样/uff0c用下标的方式去访问属性/uff0c通过所请求属性的字符串名得到并返回想要的值 #### 基本使用 - 错误的代码 ```swift struct Person { } let p = Person() // 结构体没有定义name属性/uff0c所以会报错 // Value of type 'Person' has no member 'name' print(p.name) ``` - 有了动态成员查找 ```swift // 标记 @dynamicMemberLookup struct Person { // 实现方法 subscript(dynamicMember member: String) -> String { let properties = ["name":"Zhangsan", "age": "20", "sex": "男"] return properties[member, default: "unknown property"] } } let p = Person() print(p.name) // 打印 Zhangsan print(p.age) // 打印 20 print(p.sex) // 打印 男 ``` **解读** - 声明了`@dynamicMemberLookup`后/uff0c即使属性没有定义/uff0c但是程序会在运行时动态的查找属性的值/uff0c调用`subscript(dynamicMember member: String)`方法来获取值。 - `subscript(dynamicMember member: String)`方法的返回值类型根据访问属性的类型决定。 - 由于安全性的考虑/uff0c如果实现了这个特性/uff0c返回值不能是可选值/uff0c一定要有值返回。 #### 多类型查找 既然是动态查找/uff0c如果两个属性类型不同/uff0c怎么办/uff1f解决办法是重载`subscript(dynamicMember member: String) `方法。和泛型的逻辑类似/uff0c通过类型推断来选择对应的方法。`但是此时调用的时候/uff0c所有属性必须显示声明类型/uff0c否则会报错`。 ```swift @dynamicMemberLookup struct Person { subscript(dynamicMember member: String) -> String { let properties = ["name":"Zhangsan", "sex": "男"] return properties[member, default: "unknown property"] } subscript(dynamicMember member: String) -> Int { let properties = ["age": 20] return properties[member, default: 0] } } let p = Person() // 类型必须明确 let name: String = p.name print(name) // 打印 Zhangsan let age: Int = p.age print(age) // 打印 20 let sex: String = p.sex print(sex) // 打印 男 ``` ## @dynamicCallable #### 介绍 Swift 5 中引入了一个新的语法`@dynamicCallable`/uff08动态可调用/uff09。使用`@dynamicCallable`标记了目标以后/uff08类、结构体、枚举、协议/uff09/uff0c实现`dynamicallyCall `方法后/uff0c目标可以像调用函数一样使用。 #### 核心内容 - `@dynamicCallable`/uff1a标记类、结构体、枚举、协议 - `dynamicallyCall `/uff1a实现该方法/uff0c可以像调用函数一样去调用类型/uff0c需要指定接收的参数和参数类型。 #### 基本使用 ```swift // 标记 @dynamicCallable struct Person { // 实现方法一 func dynamicallyCall(withArguments: [String]) { for item in withArguments { print(item) } } // 实现方法二 func dynamicallyCall(withKeywordArguments: KeyValuePairs
本文由 投稿者 创作,文章地址:https://blog.isoyu.com/archives/swiftxuexizhidynamicmemberlookupyudynamiccallable.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:9月 21, 2019 at 02:08 上午