Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Xcode telling me to add .map { $0.rawValue } when I can just do ?.rawValue?

I have this code:

enum Enum: String {
    case A = "A"
}

let s: String? = Enum(rawValue: "A")

Of course, it does not compile. Normally, I fix it this way:

let s: String? = Enum(rawValue: "A")?.rawValue

However, Xcode says that I should add .map { $0.rawValue }:

enter image description here

This is weird because clearly, Xcode is aware that accessing rawValue can turn Enum into a String. But why does it suggest to do it using map? Why not just access it directly?

I thought Xcode would think this way:

I've got a string constant on the left and an enum whose raw value is string. The types are not compatible, but I know rawValue can turn the enum into a string. I'll just suggest the user to add ?.rawValue!

What is Xcode's "thinking process" behind this?

P.S. My intention here is to check whether "A" is a valid raw value for an enum. If it is, assign it to s, otherwise assign nil. I know this is not very practical, but I'm just concerned with Xcode's behaviour.

like image 910
Sweeper Avatar asked Mar 06 '17 17:03

Sweeper


2 Answers

João Marcelo Souza's third answer is exactly correct. .map is the Optional safe-unwrapping method par excellence. Enum(rawValue: "A").map{$0.rawValue} is Enum(rawValue: "A")?.rawValue.

The problem is merely that we are all so used to using the second one (syntactic sugar) that we forget that the first one is how the Swift compiler actually thinks, under the hood.

Example:

var i : [Int]? = [7]
i.map {$0.count} // 1
i?.count // 1

i = nil
i.map {$0.count} // nil
i?.count // nil
like image 124
matt Avatar answered Nov 16 '22 06:11

matt


It's not specific to Enum. In fact, all Optional instances implement the map function:

let possibleNumber: Int? = Int("4")
let possibleSquare = possibleNumber.map { $0 * $0 }
print(possibleSquare) // Prints "Optional(16)"

I am not sure why Xcode suggests that instead of just .rawValue but I can think of a few possible reasons:

  1. Alphabetical order.
  2. You may want to perform some operation on the unwrapped value.
  3. Maybe foo?.bar is just syntax sugar for foo.map { $0.bar }
like image 21
João Souza Avatar answered Nov 16 '22 05:11

João Souza