簡體   English   中英

Swift 函數返回兩種不同的類型

[英]Swift function returning two different types

我需要一個可以根據輸入的參數返回StringInt的函數,例如:

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

使用枚舉

您可以使用具有關聯值的枚舉來實現您正在尋找的行為。 它們很像 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)
}

我遇到了類似的問題,我以這種方式解決了(您可以使用 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

我建議使用帶有可選值的元組,然后創建代碼來相應地解包它們。

應該謹慎使用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
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM