马上就要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还得抓紧啊.
这篇就到这里了,感谢观赏 :)