简体   繁体   English

Swift 函数返回两种不同的类型

[英]Swift function returning two different types

I need a function that can return either a String or an Int depending on the parameters entered eg:我需要一个可以根据输入的参数返回StringInt的函数,例如:

func getValue (type: String) -> (String || Int) {  //this line is obviously wrong
    if type == "type1" {
        return "exampleString"
    }
    else if type == "type2"
        return 56
    }
}

Use an Enumeration使用枚举

You can use an enumeration with associated values to achieve the behaviour you're looking for.您可以使用具有关联值的枚举来实现您正在寻找的行为。 They're much like a nicer version of C's unions.它们很像 C 的联合的更好版本。

enum Foo { //TODO: Give me an appropriate name.
    case type1(String)
    case type2(Int)
    
    static func getValue(type: String) -> Foo {
        switch (type) {
            case "type1": return type1("exampleString")
            case "type2": return type2(56)
            default: fatalError("Invalid \"type\"");
        }
    }
}

let x = Foo.getValue(type: "type1")

x must be consumed conditionally, by switching on its type and responding accordingly: x必须有条件地消耗,通过打开它的类型并相应地响应:

switch x {
    case .type1(let string): funcThatExpectsString(string)
    case .type2(let int): funcThatExpectsInt(int)
}

I faced a similar problem and I solved in this way (you can use default associated value introduced in Swift 5.1 and opaque return type)我遇到了类似的问题,我以这种方式解决了(您可以使用 Swift 5.1 中引入的默认关联值和不透明的返回类型)

class PersistanceHelper {

    enum PersistenceType {
        case userStatus(status: String = "")
        case firstAccess(isFirstAccess: Bool = true)
        case biometricsEnabled(isBiometricsEnabled: Bool = true)
        case notificationToken(token: String = "")

        func getKey() -> String {
            switch self {
            case .userStatus        : return "userStatusKey"
            case .firstAccess.      : return "firstAccessKey"
            case .biometricsEnabled : return "biometricsEnabledKey"
            case .notificationToken : return "notificationTokenKey"
            }
        }
    }

    static func save(_ objectType: PersistenceType) {
        switch objectType {
        case .userStatus(let payload), .notificationToken(let payload):
            UserDefaults.standard.set(payload, forKey: objectType.getKey())
        case .firstAccess(let payload), .biometricsEnabled(isBiometricsEnabled: let payload):
            UserDefaults.standard.set(payload, forKey: objectType.getKey())
        }
    }

    static func load<T>(_ objectType: PersistenceType) -> T? {
        UserDefaults.standard.object(forKey: objectType.getKey()) as? T
    }

}

And then use it where you need...然后在需要的地方使用它......

PersistanceHelper.save(.notificationToken(token: "93028184-87be-4a62-bcc9-70ec08d6fe7e"))
PersistanceHelper.save(.biometricsEnabled(isBiometricsEnabled: true))

if let token: String = PersistanceHelper.load(.notificationToken()),
    let isBiometricEnabled: Bool = PersistanceHelper.load(.biometricsEnabled()) {
    print(token)
    print(isBiometricEnabled)
}

The enums with associated values allow to write a self explaining code... at least to me :D具有关联值的枚举允许编写自解释代码......至少对我来说:D

I'd suggest using a tuple with optional values then create code to unwrap them accordingly.我建议使用带有可选值的元组,然后创建代码来相应地解包它们。

The type Any should be used sparingly, the fact that you know it's either a String or Int means the tuple could be the most appropriate solution in your use case.应该谨慎使用Any类型,事实上,您知道它是StringInt意味着元组可能是您用例中最合适的解决方案。

func someFuction(type: String) -> (String?, Int?) {
    //Do stuff here
}

Unwrap optional switch example:展开可选开关示例:

let sometuple: (string: String?, int: Int?) = ("Hi", 10)

switch sometuple {
    case let (.some(s), .some(i)):
        print("String: \(s), Int: \(i)")

    case let (.some(s), nil):
        print(s)

    case let (nil, .some(i)):
        print(i)

    case (nil, nil):
        print("Nothing")

}
//prints "String: Hi, Int: 10"

The reason this works is because Optional is an enum:这样做的原因是因为Optional是一个枚举:

enum Optional<T> {
    case some(x:T)
    case none
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM