Reputation: 61774
This is the case:
public enum NodeFeature: UInt16 {
case relay = 0x01
case proxy = 0x02
case friend = 0x04
case lpn = 0x08
}
public struct NodeFeatures {
public let rawValue: UInt16
public init(rawValue: UInt16) {
self.rawValue = rawValue
}
public init(features: NodeFeature...) {
var rawValue = UInt16(0)
for feature in features {
rawValue |= feature.rawValue
}
self.rawValue = rawValue
}
public func hasFeature(_ feature: NodeFeature) -> Bool {
return rawValue & feature.rawValue > 0
}
}
And this is a response from server:
"feature": {
"relay": true,
"proxy": false,
"friend": false,
"lowPower": false
}
Now I need to create an instance of NodeFeatures
with only true
values:
var features = [NodeFeature]() // how to declare and prepare the list of args?
if true {
features.append(.first)
} else if true {
features.append(.third)
}
let wrapper = NodeFeatures(features: features) //... to pass it as a variable to the initializer.
But the error is following:
Cannot convert value of type '[NodeFeature]' to expected argument type 'NodeFeatures'
Upvotes: 1
Views: 345
Reputation: 539685
You cannot pass an array to a function taking a variadic argument, or dynamically "build" a variadic argument list, compare e.g. Passing an array to a function with variable number of args in Swift.
But fortunately, the type has another initializer
public init(rawValue: UInt16)
which you can use in different ways.
Option 1: Use an integer bit mask to assemble the features instead of an array:
var rawFeatures = UInt16(0)
if condition {
rawFeatures |= NodeFeature.relay.rawValue
} else if condition {
rawFeatures |= NodeFeature.proxy.rawValue
}
let wrapper = NodeFeatures(rawValue: rawFeatures)
Option 2: Keep your array, but compute the combined raw value
to create the NodeFeatures
value:
var features = [NodeFeature]()
if condition {
features.append(.relay)
} else if condition {
features.append(.proxy)
}
let rawFeatures = features.reduce(0, { $0 | $1.rawValue })
let wrapper = NodeFeatures(rawValue: rawFeatures)
Option 3: Define another initializer taking an array argument in an extension:
extension NodeFeatures {
public init(features: [NodeFeature]) {
let rawValue = features.reduce(0, { $0 | $1.rawValue })
self.init(rawValue: rawValue)
}
}
Now you can pass your array directly:
var features = [NodeFeature]()
if condition {
features.append(.relay)
} else if condition {
features.append(.proxy)
}
let wrapper = NodeFeatures(features: features)
Upvotes: 2