可以在 Swift 中将通用子 类 与函数构建器一起使用吗?

Can one use generic sub classes with function builders in Swift?

在使用函数生成器时,我无法将可变 return 生成器闭包与 subclassing + 泛型一起用于对象。 Swift Playground 可以在这里找到。

首先,让我们定义我们的函数生成器。在这种情况下,我将使用支持数组 + 可变参数初始化以及泛型的一个:

@_functionBuilder struct Builder<T> {

    static func buildBlock(_ items: T...) -> [T] {
        items
    }

    static func buildBlock(_ items: [T]) -> [T] {
        items
    }
}

接下来,我定义了一个支持构建器初始化的通用容器对象,并保留了一个对象数组。

class Container<T> {

    let items: [T]

    init(@Builder<T> builder: () -> [T]) {
        self.items = builder()
    }
}

最后,我对这个对象进行了子class定义“导航控制器”抽象:

  struct View { }

  final class NavigationController: Container<View> { }

  let nav = NavigationController {
      View()
  }

这是 Xcode 产生以下错误的地方:Cannot convert value of type 'View' to closure result type '[View]'

这看起来很奇怪,因为函数构建器应该知道使用可变参数初始化器而不是数组初始化器,但是不知道。

为了检验我的理论,我定义了一个对象,没有子class另一个对象,但使用了我的通用[=17]中定义的构建器语法=]实施。

  class Nav {

      let views: [View]

      init(@Builder<View> builder: () -> [View]) {
          views = builder()
      }
  }

  let y = Nav {
      View()
  }

这项工作很好,编译和 运行s 没有问题。似乎 subclassing 与泛型相结合会使编译器混淆使用哪个函数构建器初始化定义,return 是数组还是 return 是可变参数列表。

有没有人运行以前参与过这个?

此问题与泛型无关。这里发生的是 automatic initializer inheritance 没有“继承”属性 @Builder<T>,因此有效地,NavigationController 初始值设定项具有以下形式:

init(builder: () -> [View]) {...}

您可以覆盖 init:

final class NavigationController: Container<View> {
    override init(@Builder<View> builder: () -> [View]) {
        super.init(builder: builder)
    }
}