在Swift中,函数返回两种以上类型的最佳方法吗?

时间:2018-08-17 09:54:27

标签: swift optimization enums tuples

我需要具有可以返回安全的随机 String Data 以及将来可能与其他类型扩展的函数。

我开始寻找建议,并发现可以通过枚举故事完成。

我决定继续进行枚举

我的实现:

enum SecureRandomInput {
    case forString
    case forData
}


enum SecureRandomOutput {
    case forString(String)
    case forData(Data)

    static func generate(with type: SecureRandomInput, bytesCount: Int) -> SecureRandomOutput {
        var randomBytes = [UInt8](repeating: 0, count: bytesCount)
        let _ = SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomBytes)
        switch type {
        case .forString:
            return SecureRandomOutput.forString(randomBytes.map({ String(format: "%02hhx", $0) }).joined(separator: ""))
        case .forData:
            return SecureRandomOutput.forData(Data(bytes: randomBytes, count: bytesCount))
        }
    }
}

所以问题是:

1)在特定情况下使用枚举比元组更灵活吗?

2)您对那部分代码有什么建议吗? (还有什么可以做得更好的)

3)在Swift 4中,还有其他方法可以实现所需的行为吗? (没有枚举和元组)

2 个答案:

答案 0 :(得分:1)

  1. 我同意你的观点,枚举是区分不同行为而不是创建大量元组的更清晰方法。

  2. 代码是非常标准的。

  3. IMO,如果两种结果都有大量共享数据(初始化/生成某些内容,例如SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomBytes)等),则这种情况也可以由常规类或结构处理。到目前为止,它很好,但是将来它可能是重构代码的一种选择。

答案 1 :(得分:1)

另一种方法是使用闭包和泛型

func generate<T>(bytesCount: Int, convert: ([UInt8]) ->T ) -> T {
    var randomBytes = [UInt8](repeating: 0, count: bytesCount)
    let _ = SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomBytes)
    return convert(randomBytes)
}

let x = generate(bytesCount: 7) {
    return Data(bytes: $0, count: $0.count)
}

let y = generate(bytesCount: 7) { bytes in
    return bytes.map({ String.init(format: "%02hhx", $0) }).joined(separator: "")
}