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
}
}
(This harks back to the old enums being just int constants)
The problem is, I have several other int-based enums where I would like to introduce similar functionality, but without duplicating code.
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.
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).
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.
Yes, enums can conform protocols. You can use Swift's own protocols or custom protocols. By using protocols with Enums you can add more capabilities.
Cases as functions Finally, let's take a look at how enum cases relate to functions, and how Swift 5.3 brings a new feature that lets us combine protocols with enums in brand new ways. A really interesting aspect of enum cases with associated values is that they can actually be used directly as functions.
Enumerations in Swift are much more flexible, and don't have to provide a value for each case of the enumeration. If a value (known as a raw value) is provided for each enumeration case, the value can be a string, a character, or a value of any integer or floating-point type.
In Swift, an enum (short for enumeration) is a user-defined data type that has a fixed set of related values. We use the enum keyword to create an enum. For example, enum Season { case spring, summer, autumn, winter } Here, Season - name of the enum.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With