为基于Int的任意枚举定义Swift协议 [英] Defining a Swift Protocol for Arbitrary, Int-based Enums

查看:116
本文介绍了为基于Int的任意枚举定义Swift协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代表颜色的枚举,并且我添加了几种方法来方便地基于对原始原始值的算术运算来获取新实例:

I have this enumeration representing a color, and I have added several methods to conveniently obtain new instances based on arithmetic operations on the original's raw value:

enum Color : Int
{
    case Red = 0
    case Green
    case Blue

    case Cyan
    case Magenta
    case Yellow


    static func random() -> Color
    {
        return Color(rawValue: Int(arc4random_uniform(6)))!
    }

    func shifted(by offset:Int) -> Color
    {
        return Color(rawValue: (self.rawValue + offset) % 6)!
        // Cyclic: wraps around
    }
}

(这让人想起原来的枚举只是int常量)

(This harks back to the old enums being just int constants)

问题是,我还有其他几个基于int的枚举,我想引入类似的功能,但是没有复制代码。

The problem is, I have several other int-based enums where I would like to introduce similar functionality, but without duplicating code.

我想我应该在 RawRepresentable 上定义协议扩展,其中 RawValue == Int

I think I should define a protocol extension on RawRepresentable where RawValue == Int:

extension RawRepresentable where RawValue == Int
{

...但这就是我对语法的理解的结尾。

...but that's where my understanding of the syntax ends.

理想情况下,我想要求使用静态方法返回个案数,并提供 random() shifted(_:)会考虑到这一点(而不是此处的硬编码6)。

Ideally, I would like to require a static method returning the number of cases, and a provide default implementation of both random() and shifted(_:) above that takes that into account (instead of the hard-coded 6 here).

结论::我已经接受 Zoff Dino的回答。即使 Rob Napier给出的答案正是我所要的,但事实证明我所要的不是毕竟是最优雅的设计,而其他答案则是更好的方法。不过,我对两个答案都赞成。谢谢大家。

CONCLUSION: I have accepted the answer by Zoff Dino. Even though the answer given by Rob Napier is exactly what I asked for, it turns out what I was asking for was not the most elegant design after all, and the other answer suggests a better approach. Still, I have upvoted both answers; thanks everyone.

推荐答案

您应该扩展自定义协议,而不要扩展 RawRepresentable 。试试这个:

You should extend your custom protocol instead of RawRepresentable. Try this:

protocol MyProtocol {
    static var maxRawValue : Int { get }

    static func random() ->  Self
    func shifted(by offset: Int) -> Self
}

enum Color : Int, MyProtocol
{
    case Red = 0
    case Green
    case Blue

    case Cyan
    case Magenta
    case Yellow

    // The maximum value of your Int enum
    static var maxRawValue: Int {
        return Yellow.rawValue
    }
}

extension MyProtocol where Self: RawRepresentable, Self.RawValue == Int {
    static func random() -> Self {
        let random = Int(arc4random_uniform(UInt32(Self.maxRawValue + 1)))
        return Self(rawValue: random)!
    }

    func shifted(by offset: Int) -> Self {
        return Self(rawValue: (self.rawValue + offset) % (Self.maxRawValue + 1))!
    }
}

let x = Color.random()
let y = x.shifted(by: 1)

这篇关于为基于Int的任意枚举定义Swift协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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