我有一个简单的基础struct,我将在此基础上进行构建。现在它有一个字段,一个 Int。
struct Card: CustomStringConvertible {
let value: Int
init(value: Int) {
self.value = value
}
var description: String {
return "\(String(value))"
}
}
Run Code Online (Sandbox Code Playgroud)
如果我这样做,我就会得到卡来打印它的价值
let c = Card(value: 1)
print(c)
Run Code Online (Sandbox Code Playgroud)
现在,如果我将卡片数组放入 CardController 中,如下所示:
class CardController: ObservableObject {
@Published
var cards: [Card] = [
Card(value: 1),
Card(value: 2),
Card(value: 3)
]
Run Code Online (Sandbox Code Playgroud)
Picker(selection: $selectedCardValue, label: Text("Choose a card")) {
ForEach(0..<cardController.cards.count) {
Text(self.cardController.cards[$0])
}
}
Text("You selected \(selectedCardValue)")
Run Code Online (Sandbox Code Playgroud)
我会得到错误Initializer 'init(_:)' requires that 'Card' conform to StringProtocol。我不确定为什么会收到此错误。如果我只是将 更改为和 值cards的类型,则代码可以正常工作。[String]["1", "2", "3"]
知道这里出了什么问题吗?
正如 E.Coms 指出的,解决方案是使用以下方法之一:
Text(self.cardController.cards[$0].description)
Text(String(describing: self.cardController.cards[$0]))
下面解释了 为什么必须在Text初始化程序中执行此操作,而不是在print().
查看两个初始化程序Text:
init(verbatim content: String)(文档)
init<S>(_ content: S) where S : StringProtocol(文档)
您必须传递 aString或 a Substring,这是唯一符合 的两种类型StringProtocol。在这种情况下,即使您的类型符合CustomStringConvertible,您仍然传递Card.
将此与类似函数进行对比print:
func print(_ items: Any..., separator: String = " ", terminator: String = "\n")(文档)
请注意,该print函数的参数由 表示Any,其解释为
Any 可以表示任何类型的实例,包括函数类型。
然后 print 函数将您传递给它的任何内容转换为String:
每个项目的文本表示与通过调用 String(item) 获得的文本表示相同。
String有一个初始化程序,它采用符合该属性的类型CustomStringConvertible并返回该description属性。
print(Card())所以你可以写和不写的原因Text(Card()是因为 print 函数有一个中间步骤String可以理解你对 的一致性CustomStringConvertible,但Text不能。如果Text允许您传递任何类型,它会更加模糊(“这种类型的文本表示是什么?”不一定立即显而易见,因为它取决于一组分层协议),并且 SwiftUI 需要做更多工作系统,它已经做了很多事情。
| 归档时间: |
|
| 查看次数: |
12809 次 |
| 最近记录: |