Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enum's rawValue property not recognized

Tags:

enums

swift

I'm using Xcode 6's playground to try out enums in Swift:

enum Rank: String
{
    case One = "One", Two="Two"

    init(rawValue : String)
    {
        self.rawValue = rawValue
    }
}

I want to override init so that the enum can be initialized using it's rawValue as argument. But I get an error:

enter image description here

But according to the Apple's Swift guide my code should be correct.

like image 274
Ramy Al Zuhouri Avatar asked Oct 18 '14 20:10

Ramy Al Zuhouri


People also ask

What is rawValue in enum?

If you define an enumeration with a raw-value type, the enumeration automatically receives an initializer that takes a value of the raw value's type (as a parameter called rawValue ) and returns either an enumeration case or nil . You can use this initializer to try to create a new instance of the enumeration.

What is rawValue in Swift?

A Swift enum can either have raw values or associated values. Why is that? It's because of the definition of a raw value: A raw value is something that uniquely identifies a value of a particular type. “Uniquely” means that you don't lose any information by using the raw value instead of the original value.

Can you give useful examples of enum associated values?

Let's see an example, enum Distance { // associate value case km(String) ... } Here, (String) is additional information attached to the value km . It represents that the value of km can only be a String .

What is associated value?

The association value of a stimulus is a measure of its meaningfulness. It is a strong predictor of how easy it is to learn new information about that stimulus, for example to learn to associate it with a second stimulus, or to recall or recognize it in a memory test.


2 Answers

The conversion methods between enums and their raw values changed between Xcode 6.0 and Xcode 6.1. The fromRaw() and toRaw() method have been replaced by a (failable) initializer and a rawValue property:

Xcode 6.0:

// raw value to enum:
if let rank = Rank.fromRaw("One") { }

// enum to raw value:
let str = rank.toRaw()

Xcode 6.1:

// raw value to enum:
if let rank = Rank(rawValue: "One") { }

// enum to raw value:
let str = rank.rawValue
like image 89
Martin R Avatar answered Oct 23 '22 04:10

Martin R


Martin's answer is completely right.

Here is a different view that more directly answers your question.

In Xcode 6.0, an enum doesn't have a rawValue property. rawValue was added in Xcode 6.1 but note that it is a read-only computed property, so you can't assign to it in Xcode 6.1 either.

In Xcode 6.1, it is unnecessary to implement an initializer that takes a rawValue because that has already been provided natively by the language. If you were trying to imitate that behavior in Xcode 6.0, then you might try something like:

enum Rank: String
{
    case One = "One", Two="Two"

    init(rawValue : String)
    {
        self = Rank.fromRaw(rawValue)
    }
}

but the problem with this is that fromRaw returns an optional enum value because the rawValue string might correspond to any enum value.

So what do you do at this point? You could add a ! to force unwrap the value:

self = Rank.fromRaw(rawValue)!

but this would crash if you tried to create an enum with an invalid raw value.

You could treat one of the enum values as a default and use the nil coalescing operator ?? to safely unwrap it:

self = Rank.fromRaw(rawValue) ?? One

which would avoid a crash, but would probably lead to unexpected behavior on the part of your program.

What you can't do in Xcode 6.0 is have the init return an optional value. This capability was added in Xcode 6.1 and it was exactly this new capability that allowed them to change fromRaw() from a function in Xcode 6.0 to an optional initializer in Xcode 6.1.

like image 40
vacawama Avatar answered Oct 23 '22 04:10

vacawama