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

时间:2016-10-14 02:35:38

标签: ios swift function

我需要一个可以返回StringInt的函数,具体取决于输入的参数,例如:

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

3 个答案:

答案 0 :(得分:21)

使用枚举

您可以使用具有关联值的枚举来实现您正在寻找的行为。它们就像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必须有条件地使用,方法是打开它的类型并做出相应的响应:

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

答案 1 :(得分:0)

我建议使用带有可选值的元组,然后创建代码以相应地解包它们。

应谨慎使用Any类型,事实上您知道它是StringInt意味着元组可能是您用例中最合适的解决方案。

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

打开可选开关示例:

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"

这可行的原因是因为Optional是一个枚举:

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

答案 2 :(得分:0)

我遇到了类似的问题,并且以这种方式解决了(您可以使用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
    }

}

然后在需要的地方使用它...

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

具有关联值的枚举允许编写自解释代码...至少对我来说:D