美文网首页
iOS @resultBuilder 结果构造器

iOS @resultBuilder 结果构造器

作者: 迷路的小小 | 来源:发表于2023-01-31 10:01 被阅读0次

@resultBuilder结果构造器,以注释器的方式优雅的实现工厂模式。
类:

struct Factory {
    var name: String
}

一、buildBlock(_:)

@resultBuilder必须实现的方法,是结果构造器的主体方法;

@resultBuilder
struct FactoryBuilder {
    static func buildBlock(_ singles: Factory...) -> [Factory] {
        return singles
    }
    
    static func buildBlock(_ components: String...) -> [Factory] {
        return components.map({ Factory(name: $0) })
    }
}

用法:

@FactoryBuilder
static func factories() -> [Factory] {
    Factory(name: "option 1")
    Factory(name: "option 2")
}
@FactoryBuilder
static func factoriesUseString() -> [Factory] {
    "option 1"
    "option 2"
}

二、buildEither(first:)buildEither(second:)

此二方法需同时实现,主要用于实现if-elseswitch条件语句,如:

static func buildEither(first component: [Factory]) -> [Factory] {
    component
}
static func buildEither(second component: [Factory]) -> [Factory] {
    component
}

用法:

@FactoryBuilder
static func factories() -> [Factory] {
  if flag1 == 0 {
    Factory(name: "option 1")
  } else {
    Factory(name: "option 2")
  }
}

三、buildArray(_:)

此方法用于实现for、while等循环语句,如:

static func buildArray(_ components: [[Factory]]) -> [Factory] {
    components.flatMap({ $0 })
}

使用时可以发现,Cannot pass array of type '[Factory]' as variadic arguments of type 'Factory'
分析后可以看到,需要实现一个可以接收数组的buildBlock(_:)方法

如:

static func buildBlock(_ components: [Factory]) -> [Factory] {
    return components
}

但实际操作下来,使用协议统一传参是最好的方案,如:

protocol Factoryer {
    var asFactories: [Factory] { get }
}
@resultBuilder
struct FactoryBuilder {
    static func buildBlock(_ singles: Factoryer...) -> [Factory] {
        return singles.flatMap({ $0.asFactories })
    }
    
    static func buildArray(_ components: [[Factory]]) -> [Factory] {
        return components.flatMap({ $0 })
    }
}

用法:

@FactoryBuilder
static func factoriesUseArray() -> [Factory] {
    for i in 0..<3 {
        Factory(name: "option \(i)")
    }
}

四、buildOptional(_:)

该方法主要用于实现可选项。如:

  • Factory对象非一定存在
let flag1: Int = 0
if flag1 == 0 {
   Factory(name: "option 1")
}
  • Factory对象非一定存在,但存在else if
    需要注意的是,如果有二种以上的结果,需要同时实现buildEither(first:)buildEither(second:)。如:
let flag1: Int = 0
if flag1 == 0 {
   Factory(name: "option 1")
} else if flag1 == 1 {
   Factory(name: "option 2")
}

五、buildExpression(_:)

buildExpression(_:)会在buildBlock(_:)之前执行。
它允许结果构建器区分表达式类型和组件类型,为语句表达式提供上下文类型信息。如:

static func buildExpression(_ expression: String...) -> [Factory] {
    return expression.map({ Factory(name: $0) })
}
static func buildExpression(_ expression: Factoryer...) -> [Factory] {
    return expression.flatMap({ $0.asFactories })
}

用法:

@FactoryBuilder
static func factoriesUseString() -> [Factory] {
    "option 1"
    "option 2"
    "option 3"
}

六、buildLimitedAvailability(_:)

用于将 buildBlock(_:) 在受限环境下(例如if #available)产生的部分结果转化为可适合任何环境的结果,以提高 API 的兼容性。

七、buildFinalResult(_:)

用于对最外层的 buildBlock(_:) 结果的再包装。例如,让结果构建器隐藏一些它并不想对外的类型(转换成可对外的类型)。

相关文章

  • 刘铁猛C#(9)方法的定义、调用与调试(下)

    Class Student 还没有声明构造器,默认构造器打印输出的结果是0(初始化的结果)。 构造器的组成 有效的...

  • 【Java补充】对象构造

    运行结果 案例中使用的特性 重载构造器 用 this(...) 调用另一个构造器 无参数构造器 对象初始化块 静态...

  • 在构造器中调用构造器

    运行结果: 构造器Flower(String s, int petals) 表明:尽管可以用this调用一个构造器...

  • 静态初始化块

    执行结果: 静态ROOT静态Mid静态Leaf普通ROOT无参数构造器ROOT普通Mid无参数构造器Mid有参数构...

  • java编程思想5-初始化与清理

    1 构造器 不接受任何参数的构造器叫做默认构造器,如果没有编写构造器,则会自动创建无参构造器。如果有构造器,则不会...

  • Initialization in Swift

    简介 *自定义构造过程 *默认构造器 *值类型的构造器代理 *类的继承和构造过程 *可失败构造器 *必需构造器 *...

  • 构造器模式-iOS实践

    构造器模式(builder) 意图:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示适用范围:...

  • swift学习笔记

    1.swift类的构造器 swift构造器有三种:指定构造器和, 便利构造器, 默认构造器. 其中用'conve...

  • iOS开发 - 「Swift 学习」Swift的构造过程(值类型

    值类型的构造器代理 构造器通过调用其它构造器来完成实例的部分构造过程称为构造器代理,能够减少多个构造器间的代码重复...

  • Swift 定义枚举类

    添加构造器 便利构造器

网友评论

      本文标题:iOS @resultBuilder 结果构造器

      本文链接:https://www.haomeiwen.com/subject/bbrphdtx.html