文中引用到的: SnapKit Alamofire Bees
链式语法在开发很常见。iOS上的许多开源库都使用了链式语法。比如说SnapKit和Alamofire等。
像以上
SnapKit的这种情况,链式调用为了灵活的添加各种约束属性。每次调用后都是返回
ConstraintMakerExtendable的实例。 但是这样就产生了一个问题:没有办法在编译时期检查被连起来的成员结构!!
像以上的情况实际上是不能产生正确的约束,但是在编译期间编译器没有办法给出提示,因为并没有语法错误。
那么如解决这个问题呢? 在Swift上可以利用
泛型和
协议拓展
举个例子
比如动物之间只有同样的种类才可以互相喜欢。那先定义一个函数表示喜欢这个行为。
在定义两个不同的动物类
好,我们来试一下
嗯,看起来是正常工作了。Dog和Dog可以like,Dog和Cat不可以!因为like函数里的left与right两个参数类型必须要相同。不同的话,编译器就会提示错误了! 但是好像哪里不对啊!这和链式调用有个屁关系啊! 别着急。 为了达成一开始的目标。我们先定义一个协议。
然后修改下like函数。
T必须为Animal类型,这样可以使like可以使用声明在Animal协议中的方法属性等。。。 然后拓展Animal协议
当然这个时候Dog类和Cat类都要遵循Animal协议
来试一下
嗯!链式调用可以用了。 但是不对啊
这样子也可以!前面的两个是不对的cat和dog是不能like。但是编译时也没有报错。因为只要链式最后的那个对象类型相同就可以了!并没有解决问题啊! 其实我们已经快要完成了只要给动物类加个泛型用来记录左边已经链起来的类型就可以了!
这就是最后的版本了! 试一下正确的情况
错误的情况
不管链的多长,只要连起来的所有对象中有一对类型不匹配,就不能通过编译! 但是以上的例子中只保留了链起来的最后一个对象!实际的应用中,应该是要保留连起来的所有对象的。不然就没有意义了。
说了这么多!有什么实际的意义呢? 回到开头的SnapKit,使用链式调用创建约束时,就可以使用以上的方法来降低程序的错误率。因为错误的写法不能通过编译啊!虽然减少了一点点灵活性,但是安全性提高很多。
我在自己的自动布局库里就用了这种方法:点这里Bees
top和left是不能创建约束的,所以在编译时就提出了错误!