问题描述
在SwiftUI中,当我尝试使用ForEach遍历元组数组时,发现Xcode报如下报错:
Type '(currencyAbbreviation: String, currencySymbol: String)' cannot conform to 'Hashable'
代码如下:
var currencySymbolList: [(currencyAbbreviation: String,currencySymbol: String)] = [
(currencyAbbreviation:"AED",currencySymbol: "د.إ"), // 阿联酋-迪拉姆
(currencyAbbreviation:"AUD",currencySymbol: "A$"), // 澳大利亚-澳元
(currencyAbbreviation:"CAD",currencySymbol: "C$"), // 加拿大-加元
]
List {
ForEach(currencySymbolList, id: \.self) { (currencyAbbreviation,currencySymbol) // 报错行
...
}
}
经过查询了解到,当我使用元组作为ForEach的数据源时,因为元组默认不符合Hashable协议,但ForEach需要的数据元素是Hashable,因此就无法用于生成标识符。
解决方案
1、使用结构体替代元组
struct Currency: Hashable {
var currencyAbbreviation: String
var currencySymbol: String
}
struct CurrencySymbolView: View {
// 使用结构体代替元组
var currencySymbolList: [Currency] = [
Currency(currencyAbbreviation: "AED", currencySymbol: "د.إ"), // 阿联酋-迪拉姆
Currency(currencyAbbreviation: "AUD", currencySymbol: "A$"), // 澳大利亚-澳元
Currency(currencyAbbreviation: "CAD", currencySymbol: "C$") // 加拿大-加元
]
ForEach(currencySymbolList, id: \.self) { currency in
Text(currency.currencySymbol)
}
}
通过创建Currency结构体,让其遵循Hashable协议后,可以在ForEach中遍历。
2、使用元组的唯一标识符
如果需要在ForEach中遍历元组,可以考虑将元组的ID或某个字段作为唯一标识符,确保元素是可区分的。例如:
var currencySymbolList: [(currencyAbbreviation: String, currencySymbol: String)] = [
("AED", "د.إ"), // 阿联酋-迪拉姆
("AUD", "A$"), // 澳大利亚-澳元
("CAD", "C$") // 加拿大-加元
]
ForEach(currencySymbolList, id: \.0) { (currencyAbbreviation, currencySymbol) in
Text(currencySymbol)
}
在ForEach中使用id:\0来指定currencyAbbreviation作为元组的唯一标识符,ForEach会通过这个标识符来识别每个元素。
总结
推荐使用结构体来代替元组,结构体自动符合 Hashable 协议,适合用作 ForEach 的数据源。
如果需要使用元组,可以使用元组的第一个元素作为 id 来确保每个元素是唯一的。