我有一个简单的基础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 次 |
最近记录: |