Blaszard Blaszard - 2 months ago 8
Swift Question

Can I use "guard let" if you want to pass over an optional string to "rawValue:" in enum in Swift?

I want to initialize a enum from a variable of type

String?
, like:

guard let rawId = request.queryParameters["id"] else {
return
}
guard let id = MyIdentifier(rawValue: rawId) else {
return
}


In this case,
request.queryParameters["id"]
returns
String?
. Then after I ensure that it is
String
in
rawId
, I convert it into an enum instance
id
.

However, the code is dirty and I want to write it in one-line if at all possible.

However, I don't like to make it unwrapped via forced optional unwrapping, because if it can not be transformed to String, the app would end up with an error, since
rawValue:
only takes
String
. I meant something like the following, which I don't like:

guard let id = MyIdentifier(rawValue: request.queryParameters["id"]!) else {
return
}


So is it still possible to define the
guard let
in one-line, maybe using
where
and/or
case
in
guard
?

Answer

You have two conditions there, trying to combine them into one condition is not always possible.

In your exact case I believe an empty id will behave the same as a nil id, therefore nil coalescing can be used:

guard let id = MyIdentifier(rawValue: request.queryParameters["id"] ?? "") else {
    return
}

However, there is nothing dirty about splitting two checks into two statements. Code is not written to be short, it's written to be clear:

guard let rawId = request.queryParameters["id"],
      let id = MyIdentifier(rawValue: rawId) else 
   return
} 

Also, there is nothing wrong with creating a custom initializer for your enum:

init?(id: String?) {
   guard let id = id else {
      return nil
   }

   self.init(rawValue: id)
}

and then

guard let id = MyIdentifier(id: request.queryParameters["id"]) else {
    return
}
Comments