I have following enum in a class.
enum Attributes: String, CustomStringConvertible {
case eventDate
case eventName
case eventType
case country
var description: String {
return self.rawValue
}
}
When I try have the following code, compiler complains with following error.
var attributesList: [String] {
return [
Attributes.eventDate, //<-- Compiler error on this row
Attributes.eventName,
Attributes.eventType,
Attributes.country]
}
Cannot convert value of the type 'Attributes' to expected element type 'String'
Shouldn't the "CustomStringConvertible" protocol return the "description"? What is wrong in the above code?
TL;DR - It doesn't work because an array of
Attribute
s cannot be assigned to an array ofString
s, they are both mismatched types, and Swift does not do automatic conversion between types, and an explict conversion needs to be specified.In Swift, when you initialise an array using an array literal, the following happens under the hood:
words
. Since we have not specified the type of thewords
, implicitly an array is assumed. The type of the elements underlying the array is determined based on the contents of the array literal.String
types; this is easily understood by the compilerArray
) conforms to a pre-defined protocol calledExpressibleByArrayLiteral
which has an associated type constraint to matchElement
, the compiler will actually be converting our line to the followingExample:
This is how initialising with array literals work. In the above example, since we did not specify the type of array, the implicit type setting will work. If we specified a mismatched type, the assignment will fail, since
ExpressibleByArrayLiteral
requires the associatedElement
type of the array literal and the actual array you are assigning to to match.So the following fails:
This also shows that there is no implicit type conversion between
Int
andString
, even thoughInt
conform toCustomStringConvertible
.In your case, you are trying to assign an array literal consisting of
Attributes
to an array ofString
. This is a type mismatch. This is the reason it fails.If you state protocol conformance, the following line will work:
If you really want a list of string values, you need to map this to a string explicitly: