Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Swift Enums and Structs Enums Enum Members and Raw Values

.Slow.rawValue not working in addition to Speed.Slow.rawValue() in enum raw value challenge #2

While knowing ,var turtleSpeed = Speed.Slow.rawValue works, it was odd that `.Slow.rawValue wouldn't also work:

enum Speed: Int {
    case Slow = 10
    case Medium = 50
    case Fast = 100
}

var turtleSpeed = .Slow.rawValue
David Galindo
David Galindo
Courses Plus Student 2,294 Points

Hello kevin I'm not sure what it is that you are asking, but the reason that .Slow.rawValue doesn't work is because it would compile due to the fact that it doesn't recognize the member ".Slow ". the reason why is because we do not have it initialize. So that why for that challenge we need to write var turtleSpeed = Speed.Slow.rawvlaue which calls the case slow and in return we get 10 that is assign to turtleSpeed. Hope this Helps you understand. what I like to do is open up playground and play around with the code and understand better why it works. Good luck !!

5 Answers

Revisiting the documentation to make sure I'm not confusing it with Go, it seems I found out the gotcha that was shown with an earlier func declaration: For the shorthand to be inferred almost close to what I wanted it to do, the following can be done.

var turtleSpeed : Speed = .Slow

In a function declaration you of course typecast what you were expecting to be able to use the shorthand technique of .memberName; it follows you must enforce the type of the variable to be able to use the same technique to assign a member of the enum to the variable via shorthand.

But, since the type of the raw value cannot help the compiler infer that the Speed enum is being used, what I attempting to do is too ambigious to compile, consistent with the behavior of most statically compilers when a statically-typed language's ambiguous date type isn't used

Chris Jones
Chris Jones
Treehouse Guest Teacher

Since this is the accepted answer, it should be noted that your example code will not compile. You're telling the compiler that turtleSpeed is of type Speed. However, the rawValue you are assigning is an Int. Unless I am missing something else, you should get the error: "Could not find member 'Slow'" in Xcode.

Working examples:

var turtleSpeed: Speed = .Slow
println(turtleSpeed.rawValue) >>> "10"

var turtleSpeed = Speed.Slow.rawValue
println(turtleSpeed) >>> "10"

Correct, Chris Jones. I've clarified the end of my original answer.

Chris Jones
STAFF
Chris Jones
Treehouse Guest Teacher

It is not odd in this use case because it's just not valid.

var turtleSpeed = Speed.Slow.rawValue

This works because you are specifying where the member value is defined aka Speed.Slow. Assigning the rawValue to turtleSpeed effectively makes turtleSpeed of type Int. It is not an instance of Speed. All you are doing here is storing the rawValue with no reference to Speed.

var turtleSpeed = .Slow.rawValue

This does not work because turtleSpeed is a brand new variable. There is no reference to the Speed enum which is where the member values (Slow, Medium, Fast) are defined. When you say .Slow, without turtleSpeed being an instance of Speed, it doesn't know where to find this phantom value.

var turtleSpeed = Speed.Slow
println(turtleSpeed.rawValue) >>> "10"

turtleSpeed = .Medium
println(turtleSpeed.rawValue) >>> "50"

In this example, turtleSpeed is an instance of Speed with the member value set to Slow. If you option+click the turtleSpeed variable in Xcode, you'll see that it is of type Speed. Now that turtleSpeed is an instance of Speed, you can change the member value using the shorthand notation.

Hope this helps.

Chris Jones
Chris Jones
Treehouse Guest Teacher

There is another way it could be done. I didn't even think about this.

var turtleSpeed: Speed = .Slow

However, you couldn't assign the rawValue this way.

var turtleSpeed: Speed = .Slow.rawValue

Since you're declaring the variable be of type Speed, assigning the rawValue would be of type Int.

Yes, I already discovered this way shortly after your original response and my reply to it, I didn't realize I could choose my own answer as a best answer to close this thread; sorry for not clearing this up.

You can only do .MemberName when the compiler can identify which enum it belongs do. It infers it.

A good example is choosing an enum type from a method or function (UIButton control event for example). The compiler already knows that it's a control event because the method gives it that much to go with. All the developer has to do is choose which one. In that case, .MemberName would be acceptable.

This got me to realize the variable inference I wanted it to do was slightly more different than the context of function declarations and switch statements I originally saw the shorthand syntax.

Amit wasn't not kidding about the unique ways enums are handled in Swift compared to the use of iota in older, statically-typed languages.

I've always treated enums in Swift as Type.MemberName similar to how I treat enums in other languages.

It's unclear when you can do .MemberName and when you can't it seems beyond within switch statements and variable assignments.

Maybe Amit Bijlani can clarify this.

Edmund lok
PLUS
Edmund lok
Courses Plus Student 6,465 Points

enum speed:Int { case Slow =10, Medium = 50, Fast = 100 }

var turtlespeed = speed.Slow.rawValue

This doesn't address the question, but thanks for attempting to address it.