2015-04-22 66 views
9

Swift問題是否有一種使用枚舉類型的方法,其中一個案例可以具有關聯值。我應該如何使用Swift Enums實現默認關聯值?

我有一個API給了我可用的過濾器,它不太可能,但API可能會添加額外的過濾器類型。所以如果API發送一個未知的過濾器類型,我想保留與該枚舉相關的信息。

以下是我對此做出的不同想法。

我的前兩次嘗試沒有編譯。我的第三次嘗試只是覺得有點笨重。

有沒有人有更好的方式做到這一點?你認爲我不應該使用枚舉來解決這個問題嗎?

typealias APIFilterIdentifier = String 

/* Does Not Compile */ 
enum EnumTestAssociatedValeu: APIFilterIdentifier { 
    case Unknown(APIFilterIdentifier) 
    case Everyone = "everyone" 
    case Team = "myteam" 
} 

/* Does not compile */ 
enum EnumTestDefaultAssociatedValues: APIFilterIdentifier { 
    case Unknown(APIFilterIdentifier) 
    case Everyone(APIFilterIdentifier = "everyone") 
    case Team(APIFilterIdentifier = "myteam") 
} 

/* Compiles but is there a better way? */ 
enum EnumTestWithCustomInit { 

    case Unknown(APIFilterIdentifier) 
    case Everyone 
    case Team 

    init(filterIdentifier: APIFilterIdentifier) { 
     let everyone: APIFilterIdentifier = EnumTestWithCustomInit.everyoneFilterIdentifier 
     let team: APIFilterIdentifier = EnumTestWithCustomInit.teamFilterIdentifier 

     switch filterIdentifier { 
     case everyone: 
      self = .Everyone 
     case team: 
      self = .Team 
     default: 
      self = .Unknown(filterIdentifier) 
     } 
    } 

    func asIdentifer() -> APIFilterIdentifier { 
     switch self { 
     case .Everyone: 
      return EnumTestWithCustomInit.everyoneFilterIdentifier 
     case .Team: 
      return EnumTestWithCustomInit.teamFilterIdentifier 
     case .Unknown(let filterIdentifier): 
      return filterIdentifier 
     } 
    } 

    private static var everyoneFilterIdentifier: APIFilterIdentifier { 
     return "everyone" 
    } 

    private static var teamFilterIdentifier: APIFilterIdentifier { 
     return "myteam" 
    } 
} 
+1

我會愛如果有人會爲這個問題做出更好的標題。 – Tobias

+0

我有同樣的問題如何使用Swift Enums實現默認關聯值?你找到答案了嗎?謝謝 – Mariam

+2

@Mariam在Swift 1.2中是不可能的。 – Tobias

回答

8

我知道這有點舊了,但是這會爲你想要的工作嗎?

typealias FilterIdentifier = String 

enum DefaultAPIFilters: FilterIdentifier { 
    case Everyone = "everyone" 
    case Team = "team" 
} 

enum APIFilters { 
    case Default(DefaultAPIFilters) 
    case Custom(FilterIdentifier) 
} 

let everyoneFilter = APIFilters.Default(.Everyone) 
let teamFilter = APIFilters.Default(.Team) 
let clownFilter = APIFilters.Custom("clowns_only") 
+0

你如何從這個構造中獲得底層價值?例如,要獲取任意操縱的字符串 – SG1

+0

我喜歡這種方法。我想我可能會使DefaultAPIFilters成爲內部枚舉。 – Tobias

+0

什麼是默認關聯值? –

4

擴展彌敦道佩裏的回答是:

您可以添加

var underlyingString: String { 
    return getUnderlyingString(self) 
} 

的枚舉。然後定義

func getUnderlyingString(apiFilter: APIFilters) -> String { 
    switch apiFilter { 
    case .Default(let defaultAPIFilter): 
     return defaultAPIFilter.rawValue 
    case .Custom(let custom): 
     return custom 
    } 
}