swift - ResultBuilder
type
status
date
slug
summary
tags
category
icon
password
官方文档:
什么是 result builder?
Result builder 是一种声明属性,用来修饰类,结构体,枚举,利用它可以使 swift 实现嵌入领域特定语言 DSL (Domain Specific Language)。
DSL 没有计算和执行的概念,和命令式编程不同,使用的时候只需要声明规则,事实以及某些元素之间的层级和关系。我们使用 swift 和 UIKit 编写应用程序,一直以来都是命令式编程,直到 swiftUI 出现。
实际上我们已经多次接触过声明式语法,例如目前苹果推崇的 swiftUI 以及 cocopods 的 podfile 文件:
SwiftUI 的声明式语法就是通过 result builder 来实现的。如果我们查看 SwiftUI View 协议的声明,我们可以看到@ViewBuilder 属性定义的 body 变量:
ViewBuilder 就是使用 result builder 修饰之后实现的一个自定义构造器。
ResultBuilder 之前的名字是 functionbuilder,所以如果看到例如
@functionBuilder
或 @_functionBuilder
,本质是同一个东西。自定义一个 result builder
从实践出发,我们可以自己尝试着实现一个简单的例子来学习。
NSAttributedString
就是一个很好的例子,构建富文本是一件比较痛苦的事情,如果可以使用 swiftUI 的声明式语法,那不是很快乐?比如说像这样:那让我们一步步来开始尝试使用
@resultBuilder
。一、创建一个函数构造器
首先使用
@resultBuilder
属性标注一个结构体,然后我们必须要实现上面的这个方法,这个方法的含义是你想要如何通过 block 传递进来的数据构造 NSAttributedString
。传递进来的是一个或者多个 NSAttributedString
,我们通过遍历拼接之后返回。
OK,我们已经完成了最重要的一步。二、创建一个方便的初始化器
我们可以简单理解为
AttributedStringBuilder
结构体已经变成了一个简单的函数,使用的时候用 @AttributedStringBuilder
来修饰,在闭包中返回一个或者多个 NSAttributedString
,生成一个拼接好的 NSAttributedString
。
为了让我们使用起来更加的方便,我们给 NSAttributedString
和 string
加上几个扩展方法,在使用字符串创建的时候更简洁。三、大功告成
到这里已经全部完成了,让我们来试试我们的声明式富文本构造器。
以上其实已经实现了我们想要的效果,在其之上我们再扩展一些经常使用到的属性,就可以很方便的创建
NSAttributedString
了,在 github 中的仓库就是使用的 @resultBuilder
,其核心就是步骤一中的代码。除此以外,
@resultBuilder
还有一些可选的实现方法,来完善构造器,例如我们如果返回一个可选值,该如何处理?如果想要像 swiftUI 一样支持 if-else,switch,该如何处理?
这些也很简单,在官方文档中,我们可以看到还有很多构建方法,用来解决不同类型,不同数据的处理:
这些方法分别对应内部不同的元素来构建的时候需要做的操作,构建器在转译时会自动选择对应的方法。
总结
以上,我们可以看到 resultBuilder 其实很简单,同时也非常强大,通过 resultBuilder 我们可以简化非常多的代码,甚至可以自己实现一个在 UIKit 框架下 swiftUI 式的声明式构建方式,具体该如何使用,取决于你的 idea💡。
想知道使用 result builder 可以干些什么有意思的事情吗?可以在下面这个仓库中看看。
awesome-result-builders
carson-katri • Updated Nov 24, 2023
这篇文章希望能让你对 ResultBuilder 有一定的了解,更深入的学习推荐肘子的文章:
附本篇文章中的Demo代码:
- Giscus