我在操场上有这个:
func foo(printables: [Printable]) {
// do something
}
enum MenuOptions: String, Printable {
case ChangePickup = "Change Pickup Time"
case RequestSupport = "Request Support"
var description: String {
get {
return self.rawValue
}
}
}
var menuOptions: [MenuOptions] = [.ChangePickup]
foo(menuOptions)
let printables = menuOptions as [Printable]
最后两行都会产生编译错误。我希望将menuOptions
隐式地转换为[Printable]
,但编译器会抱怨[MenuOptions] is not convertible to [Printable]
错误。我错过了什么吗?
如果我menuOptions as! AnyObject as! [Printable]
编译器没有抱怨并且代码正常工作,但这看起来很脏。有趣的是,做foo(menuOptions.map { $0 })
也有效!这只是一个编译器错误吗?
答案 0 :(得分:1)
您正在尝试创建一个约束于符合Printable
协议的对象的泛型函数。只是以不同的方式定义它:
func foo<T: Printable>(printables: [T]) {
// do something
}
该功能现在可以在您的上下文中使用。它将采用符合Printable
的任何对象类型的数组。
以下是Generics上的相关文档,特别是Type Constraints。
至于为什么这样做,但你的定义没有 - 这只是Swift语法。 Printable
是一种协议,但T
是一种类型(通用,但仍然是一种类型)。您希望您的函数接受符合协议(T
)的任何类型(<T: Protocol>
)。这就是语言的设计方式。
使用menuOptions as! AnyObject as! [Printable]
可能在此示例中有效,但这是一种不好的做法。使用as!
就像告诉编译器“相信我,这会起作用”。这在有限的情况下很好,但从长远来看会让你陷入困境。使用as!
关闭编译器的类型检查,这意味着如果出现问题,它将在运行时发生,并且您的应用程序将崩溃。
同样,我强烈建议阅读上面链接的关于类型约束的文档。它详细解释了它。
答案 1 :(得分:0)
我发现这很有效。似乎Swift编译器并不那么聪明。
onBindViewHolder()
我不知道为什么这些不起作用
var menuOptions: [MenuOptions] = [MenuOptions.ChangePickup]
let printables:[Printable] = menuOptions as! [Printable]
foo(printables)