Reputation: 21091
I have enum with cities that looks like
enum Cities: String {
case la = "Los Angeles"
case ta = "Tel Aviv"
case ny = "New York"
}
And I need to pass sting with city name to one of functions that is waiting for NSString
so this code is not working and I don't understand why
let selectedCity = Cities.ny
myFunc(city : selectedCity)
I get error "Cannot convert value of type 'Cities' to expected argument type 'String!'"
Xcode is suggesting me to use Cities.ny.rawValue as selectedCity.
Upvotes: 0
Views: 1126
Reputation: 2169
I have better solution, which is much more reasonable... therefore you do this:
enum Cities {
case la
case ta
case ny
var cityString: String{
switch self{
case la:
return "Los Angeles"
case ta:
return "Tel Aviv"
case ny:
return "New York"
}
}
}
Now you need to call just this:
let selectedCity = Cities.ny.cityString
the reason behind me voting over other ideas is that rawValues should be used for recognizing the case, not for getting the values of them... But that's just my opinion :)
Upvotes: 3
Reputation: 59496
So when you pass a value to a function argument the compiler checks that it is of the correct type.
Let's declare a function that receive an Int
as parameter
func giveMeYourAge(n: Int) {
}
And now let's try to invoke that function passing something that is NOT an Int
giveMeYourAge(n: "Hello World")
Now the compiler gets angry with us ☠️
error: cannot convert value of type 'String' to expected argument type 'Int' giveMeYourAge(n: "Hello World")
And it is right (of course). Infact it is telling us that we cannot pass a String
to a function that expects an Int
indeed.
When you declare you enum (let's call it City
as properly suggested by @Honey) you create a new type City
.
enum City: String {
case la = "Los Angeles"
case ta = "Tel Aviv"
case ny = "New York"
}
City
is something TOTALLY DIFFERENT from a String
.
And we cannot use City
in place of a String
or viceversa. (Just like in the previous example Int
was totally different from String
).
So if you have a function that expects a String
as parameter
func myFunc(city : String) {
// ...
}
of course you won't be able to pass an value of type City
to it.
Now let's look at this code
class Animal { }
class Dog: Animal { }
func feed(animal: Animal) {
}
let dog = Dog()
feed(animal: dog)
Why does this code compile??? 😨
This is called polymorphism. When we write
class Dog: Animal { }
we define a new type (Dog
) that is more specific than Animal
.
Polymorphism does allow us to pass to a function that expects an Animal
as param, something that is more specific (like a Dog
).
However polymorphism has nothing to do with your example. Even if the syntax is similar.
When you define an enum using this syntax
enum City: String { ... }
Instead you are simply creating a new type City
that has an instance property (rawValue
) of type String
.
Upvotes: 4
Reputation: 36287
It's like you're trying to access a class instance, rather that the property of the instance. It won't work. Specifically what you're trying here is accessing the enum itself which is incorrect. You should access its rawValue
property.
From Apple:
You access the raw value of an enumeration case with its rawValue property:
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
Upvotes: 1
Reputation: 582
You need to specify raw value to use the string literal, because without that you are just referring to the enum itself.
let selectedCity = Cities.ny.rawValue
Upvotes: 3