SwiftUI中如何对结构体数组使用.contains方法?
结构体数组使用.contains方法的正确方式
你遇到的错误是因为appearedNames是ColoredName结构体数组,直接把String?类型的currentPerson传给contains方法是不匹配的——contains需要的是判断数组元素是否符合条件的闭包,而非字符串值。
解决方法一:使用contains(where:)闭包(推荐)
直接通过闭包检查数组中是否存在name属性匹配currentPerson的元素,同时用可选绑定安全解包currentPerson:
修改错误行的代码:
if let current = currentPerson, !appearedNames.contains(where: { $0.name == current }) { appearedNames.append(ColoredName(name: current, color: .red)) }
contains(where:)接收一个闭包,$0代表数组中的每个ColoredName元素- 我们通过
$0.name访问元素的名称属性,和已解包的current字符串做比较,判断是否存在重复项 - 可选绑定
let current = currentPerson避免了后续的空值处理,代码更安全
解决方法二:让结构体遵循Equatable协议
如果需要直接通过contains比较元素,可以让ColoredName遵循Equatable,并自定义相等判断逻辑(比如只比较name):
首先修改结构体:
struct ColoredName: Identifiable, Equatable { let id = UUID() var name: String var color: Color // 自定义相等判断,只比较name属性 static func == (lhs: ColoredName, rhs: ColoredName) -> Bool { lhs.name == rhs.name } }
然后使用时,创建一个临时的ColoredName实例来匹配:
if let current = currentPerson, !appearedNames.contains(ColoredName(name: current, color: .red)) { appearedNames.append(ColoredName(name: current, color: .red)) }
这种方式适合需要频繁按name判断相等的场景,但灵活性不如第一种闭包方式。
额外优化建议
你代码中多处使用currentPerson ?? "",用可选绑定提前解包可以让代码更简洁易读,比如两个按钮的逻辑都可以统一处理空值情况。
内容的提问来源于stack exchange,提问作者simonaus
相关产品推荐
相关产品推荐

