Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FunctionBuilder with 1 item

Tags:

swift

swift5.1

I'm trying to wrap my head around @_functionBuilder. There is one case I haven't been able to figure out.

I put together this simple example, when there are two passengers this works great. But when there is only 1 I get this error:

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")
}
like image 402
keegan3d Avatar asked Aug 18 '19 01:08

keegan3d


2 Answers

My solution is add more init function with single item Passanger return to struct Car. It will be:

struct Car {
    let passangers: [Passanger]

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

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

Hope to help you

like image 86
Thanh Vu Avatar answered Sep 18 '22 10:09

Thanh Vu


For anyone else that ends up here.

As I answered on the question referenced by CRD, there is a bug on the current implementation of function builders where it ignores the function builder when there is only one value available. It's fixed on Swift 5.3 and available on Xcode 12.

Thanh Vu's solution of making a overload works for now, but you don't even need the @PassangerBuilder annotation.

like image 32
Robuske Avatar answered Sep 22 '22 10:09

Robuske