簡體   English   中英

Swift 枚舉協議一致性

[英]Swift enum protocol conformance

我想創建一個 Swift 協議,我的不同枚舉可以遵循,所以我可以在使用枚舉的 rawValue 時使用相同的“類型”。 基本上,協議應該如下所示:

protocol SidebarCustomFilter {
    
    var image: UIImage { get }

    var filterPredicate: NSPredicate { get }
}

符合此的示例枚舉:

enum SidebarFilterLogs : String, CaseIterable, SidebarCustomFilter{
    case filterAll = "All"
    case filterThisWeek = "This Week"

    var image: UIImage {
        return UIImage(systemName: "tray.full.fill")!
    }
    
    var filterPredicate: NSPredicate {
        return NSPredicate.init(format: "TRUEPREDICATE")
    }
}

現在我想在結構中使用這個枚舉:

struct CJSidebarFilterItem: Hashable {
    private var identifier: String = ""
    var sectionType: SectionType
    var sidebarCustomFilter: SidebarCustomFilter?

    init(logsFilter: SidebarFilterLogs) {
        self.sectionType = .filters
        self.sidebarCustomFilter = logsFilter
        
        self.identifier = UUID().uuidString
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(identifier)
    }

    static func == (lhs: CJSidebarFilterItem, rhs: CJSidebarFilterItem) -> Bool {
        return lhs.identifier == rhs.identifier
    }
}

到目前為止,一切都很好。 但是,如果我嘗試對枚舉(我上面描述的協議類型)使用“rawValue”,它會給我一個錯誤

sidebarItem.sidebarCustomFilter?.rawValue // Value of type 'SidebarCustomFilter' has no member 'rawValue'

這是有道理的,因為SidebarCustomFilter只是一個協議。 但是,如果我嘗試讓它從 RawRepresentable 繼承(這應該允許它與rawValue一起使用),

protocol SidebarCustomFilter: RawRepresentable {
    
    var image: UIImage { get }

    var filterPredicate: NSPredicate { get }
}

我得到一個不同的錯誤:

var sidebarCustomFilter: SidebarCustomFilter? // Protocol 'SidebarCustomFilter' can only be used as a generic constraint because it has Self or associated type requirements

我相信這與使用associatedtype RawValueRawRepresentable有關,但我不確定如何解決它。

那么我如何讓我的協議正常工作,以使其強制只有其他枚舉符合它(因此對它使用'rawValue'是有效的)?

找到了解決方案:

protocol SidebarCustomFilter {
    var name: String { get }

    var image: UIImage { get }
    
    var filterPredicate: NSPredicate { get }
}

extension SidebarCustomFilter where Self: RawRepresentable {
    var name: Self.RawValue {
        return self.rawValue
    }
}

現在我可以使用sidebarItem.sidebarCustomFilter?.name而不是直接詢問rawValue ,它可以工作!

編輯:添加代碼以顯示其存儲方式:

struct CJSidebarFilterItem: Hashable {
    private var identifier: String = ""
    var sectionType: SectionType
    var sidebarCustomFilter: SidebarCustomFilter? // storing as generic type

    init(logsFilter: SidebarFilterLogs) {
        self.sectionType = .filters
        self.sidebarCustomFilter = logsFilter
        self.identifier = UUID().uuidString
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(identifier)
    }

    static func == (lhs: CJSidebarFilterItem, rhs: CJSidebarFilterItem) -> Bool {
        return lhs.identifier == rhs.identifier
    }
}

以及它是如何使用的:

let titleString = sidebarItem.sidebarCustomFilter?.name ?? ""

暫無
暫無

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

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