将可变参数列表分配给变量

时间:2017-06-26 10:36:10

标签: ios swift

情况就是这样:

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
    }
}

这是来自服务器的响应:

"feature": {
  "relay": true,
  "proxy": false,
  "friend": false,
  "lowPower": false
}

现在我需要创建一个只有NodeFeatures值的true实例:

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.

但错误如下:

  

无法将'[NodeFeature]'类型的值转换为预期的参数类型'NodeFeatures'

1 个答案:

答案 0 :(得分:2)

您无法将数组传递给采用可变参数的函数, 或动态"构建"一个可变参数列表,比较例如 Passing an array to a function with variable number of args in Swift

但幸运的是,该类型还有另一个初始化程序

public init(rawValue: UInt16)

您可以以不同的方式使用。

选项1:使用整数位掩码来组合要素 而不是数组:

var rawFeatures = UInt16(0)
if condition {
    rawFeatures |= NodeFeature.relay.rawValue
} else if condition {
    rawFeatures |= NodeFeature.proxy.rawValue
}
let wrapper = NodeFeatures(rawValue: rawFeatures)

选项2:保留数组,但计算合并的原始值 创建NodeFeatures值:

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)

选项3:定义另一个采用数组参数的初始值设定项 在一个扩展名中:

extension NodeFeatures {

    public init(features: [NodeFeature]) {
        let rawValue = features.reduce(0, { $0 | $1.rawValue })
        self.init(rawValue: rawValue)
    }
}

现在您可以直接传递数组:

var features = [NodeFeature]()
if condition {
    features.append(.relay)
} else if condition {
    features.append(.proxy)
}
let wrapper = NodeFeatures(features: features)