前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >@dynamicCallable

@dynamicCallable

作者头像
YungFan
发布2019-09-24 16:03:05
8380
发布2019-09-24 16:03:05
举报
文章被收录于专栏:学海无涯
介绍

Swift 5 中引入了一个新的语法@dynamicCallable(动态可调用)。使用@dynamicCallable标记了目标以后(类、结构体、枚举、协议),实现dynamicallyCall方法后,目标可以像调用函数一样使用。

核心内容
  • @dynamicCallable:标记类、结构体、枚举、协议
  • dynamicallyCall:实现该方法,可以像调用函数一样去调用类型,需要指定接收的参数和参数类型。
基本使用
代码语言:javascript
复制
// 标记
@dynamicCallable
struct Person {
    
    // 实现方法一
    func dynamicallyCall(withArguments: [String]) {
        
        for item in withArguments {
            print(item)
        }
        
    }
    
    // 实现方法二
    func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, String>){
        
        for (key, value) in withKeywordArguments {
            
            print("\(key) --- \(value)")
            
        }
        
    }
    
}

let p = Person()

p("zhangsan")
// 等于 p.dynamicallyCall(withArguments: ["zhangsan"])

p("zhangsan", "20", "男")
// 等于 p.dynamicallyCall(withArguments: ["zhangsan", "20", "男"])

p(name: "zhangsan")
// 等于 p.dynamicallyCall(withKeywordArguments: ["name": "zhangsan"])

p(name: "zhangsan", age:"20", sex: "男")
// 等于 p.dynamicallyCall(withKeywordArguments: ["name": "zhangsan", "age": "20", "sex": "男"])

解读

  • 声明了@dynamicMemberLookup后,必须实现dynamicallyCall(withArguments:)dynamicallyCall(withKeywordArguments:)两个方法中的至少一个,否则编译器会报错。
  • 当目标调用的时候,会转换成方法的调用,然后传入对应的参数与参数类型。
  • 实现了dynamicallyCall(withArguments:)
    • 参数类型根据自己需要调整,如上例[String]
    • 当目标调用的时候,参数不带标签。
    • 参数为数组时,可以理解为可变参数,调用时传入的参数可以是1个,也可以是多个。
  • 实现了dynamicallyCall(withKeywordArguments:)
    • 参数类型为KeyValuePairs,暂时可以把它当成字典来用,主要改变的是value的类型,如上例中为String
    • 当目标调用的时候,参数带标签。
注意事项
  • 如果实现dynamicallyCall(withKeywordArguments:)但没有实现dynamicallyCall(withArguments:),也可以在没有参数标签的情况下调用
  • 如果实现dynamicallyCall(withKeywordArguments:)dynamicallyCall(withArguments:)时标记为throw,则调用该类型也将被抛出throw
  • 扩展无法添加@dynamicCallable,只能添加到主要类型上
KeyValuePairs

在 Swift 5 中,之前的DictionaryLiteral类型被重命为KeyValuePairs

  • 字典有一个构造函数public init(dictionaryLiteral elements: (Key, Value)...),其中后面的那一串就是DictionaryLiteral,即KeyValuePairs
代码语言:javascript
复制
let dic = Dictionary(dictionaryLiteral: ("name","zhangsan"), ("age","20"),("sex","男"))
print(dic["name"])
  • KeyValuePairs只有一个构造函数
代码语言:javascript
复制
// 构造函数
public init(dictionaryLiteral elements: (Key, Value)...)

// 构造一个person
let person: KeyValuePairs = KeyValuePairs(dictionaryLiteral: ("name","zhangsan"), ("age","20"),("sex","男"))
  • 与字典的区别 官方介绍:字典中键值对的顺序是不可预测的。 如果您需要有序的键值对集合并且不需要Dictionary提供的快速键查找,请使用KeyValuePairs类型以获取替代方案。
意义

Swift 目前可以与 C、OC 交互。但如 Python 、 JavaScript 等则不行,如果 Swift 能够调用 Python 、JavaScript 等语言,那么毫无疑问会极大的拓展的 Swift 的边界。 想要实现这一点,@dynamicMemberLookup@dynamicCallable双剑合璧或可实现。首先通过@dynamicMemberLookup动态的返回一个函数,再通过@dynamicCallable来调用。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.09.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 核心内容
  • 基本使用
  • 注意事项
  • KeyValuePairs
  • 意义
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档