Swift4.2之新特性:动态成员(dynamicMember)和Ruby类似机制的比较

版权声明:大熊猫猪·侯佩原创或翻译作品.谢绝转载! hopy https://blog.csdn.net/mydo/article/details/82078481

马上就要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还得抓紧啊.

这篇就到这里了,感谢观赏 :)

猜你喜欢

转载自blog.csdn.net/mydo/article/details/82078481
今日推荐