马上就要9月了,iOS 12和MacOS 10.14正式版也越来越近了.这也意味着Swift 4.2和Xcode 10正式版也很快就要来了.
在这里就由本猫先聊一下Swift 4.2的一个新特性:dynamicMember.
这个特性是什么意思呢?用过Ruby语言的都知道Ruby里有一个method_missing机制,实现该机制的类将变得极端灵活:
class A def method_missing(method_name,*args,&block) print("#{method_name} #{args}") end end
简单的说,任何实现method_missing类的实例在接收到未定义的消息(因为Ruby里所有动作都是通过发送消息来调用,ObjC和Ruby都是借鉴了Smalltalk语言的这一机制)时,都会转而调用该方法.
这里未定义的方法不仅指的是类A中没有的方法,也包括A的所有父类以及与之有关系的所有模块中没有的方法.
如果你没有定义method_missing方法,那也没关系,Ruby核心类早就帮你定义了该方法.当你执行不存在的方法时,核心定义的方法会直接返回错误,提示该方法不存在.
如果你重载了核心的调用,那么基本上说你可以为所欲为,现举一例:
class A def initialize @dict = {} end def method_missing(method_name,*args,&block) if method_name == :"[]" @dict[args[0]] elsif method_name == :"[]=" @dict[args[0]] = args[1] end end end
上面短短几行代码实现了神马功能呢?你在A的实例上可以获取和设置任何名称的属性,如果该属性名称不存在则返回nil.
a = A.new a.name #返回nil a.name = "hopy" a.name #返回"hopy"
因为Ruby是一个极度弱类型的语言,所以它的字典关键字是不分类型的,你可以这么写:
a["11"] = 11 a[11] = 11 #It's OK too
以上写了这么多Ruby语言的代码,用意就是为了引出如下一句话:Swift 4.2的dynamicMember特性差不多也部分实现了这一功能.
现在我们看看如何在Swift里使用动态成员,注意如下代码现在必须在Xcode 10 beta里面执行,因为我们需要用Swift 4.2:
@dynamicMemberLookup class Foo{ private var dict:[String:Int] = [:] subscript(dynamicMember name:String)->Int?{ get{ return dict[name] } set{ dict[name] = newValue } } } let foo = Foo() foo.name = 121 foo.name
各位可以和Ruby比较一下,是否很像呢?不过不可否认的的是Ruby可以做的更多,因为它可以截获”任意方法”,任意参数,任意尾随闭包哦!!!
再深度思考下可以意识到Swift正在为将来5.0版本布局,使其更好地兼容动态语言的API接口(C#这点上现在做的更好一些),Swift还得抓紧啊.
这篇就到这里了,感谢观赏 :)