FunctionBuilder с 1 элементом

Я пытаюсь осознать @_functionBuilder. Есть один случай, в котором я не смог разобраться.

Я собрал этот простой пример, когда есть два пассажира, это отлично работает. Но когда есть только 1, я получаю эту ошибку:

error: FunctionBuilder.playground:21:5: error: cannot convert value of type 'Passanger' to closure result type '[Passanger]'

@_functionBuilder
struct PassangerBuilder {
    static func buildBlock(_ passangers: Passanger...) -> [Passanger] {
        return passangers
    }
}

struct Passanger {
    let name: String
}

struct Car {
    let passangers: [Passanger]

    init(@PassangerBuilder _ builder: () -> [Passanger]) {
        self.passangers = builder()
    }
}

Car {
    Passanger(name: "Tom")
//    Passanger(name: "Mary")
}

person keegan3d    schedule 18.08.2019    source источник


Ответы (2)


Мое решение - добавить дополнительную функцию инициализации с возвратом одного элемента Passanger в struct Car. Это будет:

struct Car {
    let passangers: [Passanger]

    init(@PassangerBuilder _ builder: () -> [Passanger]) {
        self.passangers = builder()
    }

    init(@PassangerBuilder _ builder: () -> Passanger) {
        self.passangers = [builder()]
    }
}

Надеюсь помочь вам

person Thanh Vu    schedule 18.08.2019
comment
Это сработало, спасибо, все еще надеясь найти более общее решение - person keegan3d; 18.08.2019
comment
Этот обходной путь, вероятно, не соответствует вашим ожиданиям. @PassangerBuilder можно опустить во втором init, и созданный код будет таким же, как и конструктор функций, который игнорируется. Похоже, что в конструкции компилятора / языка есть особенность, см. Конструктор функций не работает, когда только одно значение? - person CRD; 17.10.2019

Для всех, кто здесь оказывается.

Как я ответил на вопрос, на который ссылается CRD, есть ошибка в текущей реализации построителей функций, когда она игнорирует построитель функций, когда доступно только одно значение. Он исправлен в Swift 5.3 и доступен в Xcode 12.

Решение Thanh Vu по созданию перегрузки на данный момент работает, но вам даже не нужна аннотация @PassangerBuilder.

person Robuske    schedule 30.07.2020