您如何镜像Codable / CodableKeys协议的设计? [英] How can you mirror the design of the Codable/CodableKeys protocols?

查看:69
本文介绍了您如何镜像Codable / CodableKeys协议的设计?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现类似于Swift在实现 Codable的类中定义的枚举上利用 CodableKeys 协议集的方式。在我的情况下,该类为 CommandHandler ,枚举为 CommandIds ,它不需要从以下代码生成

I'm trying to achieve something similar to how Swift utilizes the CodableKeys protocol set on an enumeration defined within a class that implements Codable. In my case, the class is CommandHandler and the enumeration is CommandIds and it doesn't require on code-gen from the compiler as the enum will always be explicitly specified.

这里是我所追求的简化版本...

Here's a simplified version of what I'm after...

protocol CommandId{}
protocol CommandHandler{
    associatedtype CommandIds : CommandId, RawRepresentable
}

class HandlerA : CommandHandler{
    enum CommandIds : String, CommandId{
        case commandA1
        case commandA2
    }
}

class HandlerB : CommandHandler{
    enum CommandIds : String, CommandId{
        case commandB1
        case commandB2
        case commandB3
    }
}

func processHandler<T:CommandHandler>(_ handler:T){
    // Logic to iterate over CommandIds. <-- This is where I get stumped
}

let handlerA = HandlerA()
processHandler(handlerA)

我在这里处理 processHandler 内的代码,因为我不确定如何到达枚举来自处理程序实例的值。

I'm struggling with the code inside processHandler here because I'm not sure how to reach the enumeration's values from a handler instance.

那么我缺少了什么?获得相关枚举值的代码是什么?

So what am I missing? What would be the code to get the values of the associated enumeration?

推荐答案

您可以使用Swift的<$ c $轻松完成此操作c> CaseIterable 协议。

You can do this easily using Swift's CaseIterable protocol.

protocol CommandId: CaseIterable {
    func handle()
}

protocol CommandHandler {
    associatedtype CommandIds: CommandId, RawRepresentable
}

class HandlerA: CommandHandler {
    enum CommandIds: String, CommandId {
        case commandA1
        case commandA2

        func handle() {
            print("\(rawValue) is handled")
        }
    }
}

class HandlerB: CommandHandler {
    enum CommandIds: String, CommandId {
        case commandB1
        case commandB2
        case commandB3

        func handle() {
            print("\(rawValue) is handled")
        }
    }
}

func processHandler<T: CommandHandler>(_ handler: T) {
    // Logic to iterate over CommandIds. <-- This is where I get stumped
    T.CommandIds.allCases.forEach({ $0.handle() })
}

let handlerA = HandlerA()
processHandler(handlerA)

这篇关于您如何镜像Codable / CodableKeys协议的设计?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆