CustomStringConvertible in enum



我在类中有以下枚举。

enum Attributes: String, CustomStringConvertible {
case eventDate
case eventName
case eventType
case country
var description: String {
return self.rawValue
}
}

当我尝试使用以下代码时,编译器抱怨以下错误。

var attributesList: [String] {
return [
Attributes.eventDate, //<-- Compiler error on this row
Attributes.eventName,
Attributes.eventType,
Attributes.country]
}

无法将"属性"类型的值转换为预期的元素类型"字符串">

"CustomStringConvertible"协议不应该返回"描述"吗? 上面的代码有什么问题?

TL;DR- 它不起作用,因为不能将Attribute数组分配给String的数组,它们都是不匹配的类型,并且 Swift 不会在类型之间进行自动转换,并且需要指定显式转换。


在 Swift 中,当您使用数组文字初始化数组时,底层会发生以下情况:

let words = ["hello", "world"]
  • 编译器识别出数组文本正在分配给名为words的变量。由于我们没有指定words的类型,所以隐式假定一个数组。数组底层元素的类型是根据数组文本的内容确定的。
  • 在这种情况下,数组文本是String类型的集合;编译器很容易理解这一点。
  • 由于 LHS 类型是一个数组,RHS 结构是一个数组文字,并且由于 LHS 类型 (Array( 符合称为ExpressibleByArrayLiteral的预定义协议,该协议具有匹配Element的相关类型约束,编译器实际上会将我们的行转换为以下内容

例:

let words = [String].init(arrayLiteral: ["hello", "world"]) // we do not call this init directly

这就是使用数组文字初始化的工作方式。在上面的示例中,由于我们没有指定数组的类型,因此隐式类型设置将起作用。如果我们指定了不匹配的类型,则分配将失败,因为ExpressibleByArrayLiteral需要数组文本的关联Element类型和要分配给的实际数组进行匹配。

因此,以下操作失败:

let words:[String] = [1, 2] // array literal has Element=Int, array has Element=String

这也表明IntString之间没有隐式类型转换,即使Int符合CustomStringConvertible

在您的情况下,您正在尝试将由Attributes组成的数组文本分配给String数组。这是类型不匹配。这就是它失败的原因。

如果声明协议一致性,则以下行将起作用:

var attributesList: [CustomStringConvertible] {
return [
Attributes.eventDate,
Attributes.eventName,
Attributes.eventType,
Attributes.country
]
}
// note that we have an array of CustomStringConvertible protocol,
// each element here is still of Attributes type
// a type conforming to a protocol can be cast to an instance
// of that protocol automatically
// The above initialisation works simply because the following
// also works without any further action required
// let a:CustomStringConvertible = Attributes.country

如果你真的想要一个字符串值的列表,你需要把它显式映射到一个字符串:

var attributesList1: [String] {
return [
Attributes.eventDate,
Attributes.eventName,
Attributes.eventType,
Attributes.country
].map { $0.description }
}
var attributesList2: [String] {
return [
Attributes.eventDate.description,
Attributes.eventName.description,
Attributes.eventType.description,
Attributes.country.description
]
}

相关内容

  • 没有找到相关文章

最新更新