Swift语言中的Key-Path特性浅析
Swift语言中的Key-Path特性浅析
引
Key-Path字面理解为键路径,熟悉Objective-C语言的同学知道,OC中有一种语法叫做KVC,即简直编码,其作用是允许开发者通过字符串路径来访问对象的属性,这也是Objective-C语言动态化的一种特性。总所周知,Swift是一种强调静态类型与编码安全的语言,因此动态化本身在Swift语言中并不是一种受欢迎的特性,静态化的编程可以让更多的异常问题在编译时被检查出来,并且从开发直觉上来说,静态化也比动态化的代码逻辑更容易理解。
然而,动态化确实也可以代码极大的好处,尤其是一些特殊的应用场景中,动态化可以允许开发者在运行时决定要操作数据,可以使用简洁的代码编写出非常强大的功能逻辑。
回归正题,文本主要讨论Swift编程语言中的Key-Path特性,Key-Path与Objective-C中的KVC有些类似,其为Swift增加了一种动态访问对象属性的能力,但对KVC的完全动态化又进行了一些限制,Swift中定义了一种特殊的类型来描述对象键的路径,这就是Key-Path。那么它有什么用?怎么用呢?这是本文要介绍的重点,希望能给你带来启发。
什么是Key-Path
编程的本质是使用特定的语言来描述算法或数据。Key-Path是Swift中内置的一种类型,定义如下:
1 | class KeyPath<Root, Value> |
可以看到这个Key-Path类的定义关联了两个泛型,Root描述的是支持此Key-Path的对象本身的类型,Value描述的是此Key-Path对应的路径的属性的类型。这么讲可能有些抽象,我们通过一个小例子来看就比较清晰了。
1 | // k是一个key-path对象 |
Key-Path在定义时,语法是使用\符号,之后跟上对象类型与属性名,属性名是支持链式描述的。
自定义的类型也可以很方便的使用Key-Path,例如:
1 | struct Subject { |
可以看到,Key-Path路径除了可以链式定义,还支持数组下标。另外,如果在上下文中是可以推断出Key-Path的Root泛型具体类型时,也可以省略对象的类型部分,例如:
1 | // 34 |
在属性路径中也支持使用self来描述对象本身,例如:
1 | // 当前Teacher对象本身:t |
如果路径中的某个属性是可选的,那么在定义Key-Path时,也可以类似可选链的方式进行拆包,如下:
1 | class Class { |
Key-Path的一些应用
从语法层面上来看,Key-Path的写法非常简洁,在某些场景下,我们可以用其来代替闭包或函数。最常见的应用场景为filter、map这些方法。例如:
1 | let teachers = [Teacher(name: "A", age: 30, subject: .init(name: "A"), students: []), |