【发布时间】:2019-11-16 10:30:58
【问题描述】:
我尝试关注 WWDC 2019 的 Combine in Practice 谈话(从 26:00 分钟开始)的代码 sn-p 或查看 slides 179 ff。但它不会编译并且查看 API 某些部分对我来说没有意义(例如,使用 closure 类型的第三个参数调用 CombineLatest.init(A, B)。我尝试调整示例以便它们编译。
问题第 1/2 部分:如果我对 WWDC 2019 代码 sn-ps 有误解,谁能帮助我并告诉我?
第一个代码 sn-p(幻灯片 179)
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: CombineLatest<Published<String>, Published<String>, String?> {
return CombineLatest($password, $passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
}
我只能让这个 sn-p 至少返回给我Publisher fromCombineLatest`
- 将
Publishers枚举添加到CombineLatest的命名空间 - 移除尾随闭合
- 将
.Publisher添加到Published<String>
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher> {
return Publishers.CombineLatest($password, $passwordAgain)
}
第二个代码 sn-p(幻灯片 185)
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Map<CombineLatest<Published<String>, Published<String>, String?>> {
return CombineLatest($password, $passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map { $0 == "password1" ? nil : $0 }
}
我可以让这个 sn-p 在以下情况下编译:
- 执行为第一个 sn-p 列出的所有步骤
- 在
Map前面添加Publishers. - 将
<>移动到正确的位置 - 显式返回
Publishers.Map,并使用正确的参数upstream:
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?> {
return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
或者当包括幻灯片中的.map {} 时:
- 通过将 var 类型包装在另一个
Publishers.Map<..., String?>
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.Map<Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?>, String?> {
return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map { $0 == "password1" ? nil : $0 }
}
问题第 2/2 部分:快速的方法是什么?例如,通过使用这样的东西(不能编译):
@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: AnyPublisher<String?, Never> {
return Just($password)
.combineLatest($passwordAgain) { password, passwordAgain in
guard password == passwordAgain, password.count > 8 else { return nil }
return password
}
.map{ $0 == "password1" ? nil : $0 }
.eraseToAnyPublisher()
}
【问题讨论】:
标签: swift generics swiftui combine combinelatest