Swift 合并条件 FlatMap 结果
Swift Combine Conditional FlatMap Results
在使用 Swift Combine 时,如何为 flatMap 设置不同的 return 类型?我有我的第一个发布者,它发出一个值,然后我 flatMap 将其转换为一个新的发布者。但是,根据原始值,我可能需要 return 不同类型的不同发布者。
我在下面添加了一个基本示例。
import Combine
class Testing{
var subscriptions = Set<AnyCancellable>()
func getTestScore()->AnyPublisher<Int, Never>{
return Just(80).eraseToAnyPublisher()
}
func congratulate()->AnyPublisher<String, Never>{
return Just("Good Job!").eraseToAnyPublisher()
}
func getGPA()->AnyPublisher<Double, Never>{
return Just(2.2).eraseToAnyPublisher()
}
init() {
getTestScore()
.flatMap{ score in
if score < 70{
return self.getGPA()
} else{
return self.congratulate()
}
}
.sink { _ in } receiveValue: { value in
print(value)
}.store(in: &subscriptions)
}
}
let testing = Testing()
正如 New Dev 所说,返回条件数据类型是不可能的——除非你不想将类型擦除为 Any
。
我的建议是创建一个专门的发布者,它会在分数超过(或低于)某个限制时发布。现在使用您的新发布者创建两个独立的、类型安全的管道。我知道您要求只使用一个管道。但是,我认为这种做法会给你带来更多的好处。
请在下面找到我的工作示例:
import Combine
class Testing{
var subscriptions = Set<AnyCancellable>()
func getTestScore()->AnyPublisher<Int, Never> {
return Just(80).eraseToAnyPublisher()
}
func congratulate()->AnyPublisher<String, Never> {
return Just("Good Job!").eraseToAnyPublisher()
}
func getGPA()->AnyPublisher<Double, Never> {
return Just(2.2).eraseToAnyPublisher()
}
init() {
let scoreExceedsLimit: AnyPublisher<Bool, Never> = getTestScore()
.map { [=10=] >= 70 }
.eraseToAnyPublisher()
scoreExceedsLimit
.filter { [=10=] == true }
.flatMap { _ in self.congratulate() }
.sink(receiveValue: { value in
print("first pipeline: \(value)")
})
.store(in: &subscriptions)
scoreExceedsLimit
.filter { [=10=] == false }
.flatMap { _ in self.getGPA() }
.sink(receiveValue: { value in
print("second pipeline: \(value)")
})
.store(in: &subscriptions)
}
}
let testing = Testing()
在使用 Swift Combine 时,如何为 flatMap 设置不同的 return 类型?我有我的第一个发布者,它发出一个值,然后我 flatMap 将其转换为一个新的发布者。但是,根据原始值,我可能需要 return 不同类型的不同发布者。
我在下面添加了一个基本示例。
import Combine
class Testing{
var subscriptions = Set<AnyCancellable>()
func getTestScore()->AnyPublisher<Int, Never>{
return Just(80).eraseToAnyPublisher()
}
func congratulate()->AnyPublisher<String, Never>{
return Just("Good Job!").eraseToAnyPublisher()
}
func getGPA()->AnyPublisher<Double, Never>{
return Just(2.2).eraseToAnyPublisher()
}
init() {
getTestScore()
.flatMap{ score in
if score < 70{
return self.getGPA()
} else{
return self.congratulate()
}
}
.sink { _ in } receiveValue: { value in
print(value)
}.store(in: &subscriptions)
}
}
let testing = Testing()
正如 New Dev 所说,返回条件数据类型是不可能的——除非你不想将类型擦除为 Any
。
我的建议是创建一个专门的发布者,它会在分数超过(或低于)某个限制时发布。现在使用您的新发布者创建两个独立的、类型安全的管道。我知道您要求只使用一个管道。但是,我认为这种做法会给你带来更多的好处。
请在下面找到我的工作示例:
import Combine
class Testing{
var subscriptions = Set<AnyCancellable>()
func getTestScore()->AnyPublisher<Int, Never> {
return Just(80).eraseToAnyPublisher()
}
func congratulate()->AnyPublisher<String, Never> {
return Just("Good Job!").eraseToAnyPublisher()
}
func getGPA()->AnyPublisher<Double, Never> {
return Just(2.2).eraseToAnyPublisher()
}
init() {
let scoreExceedsLimit: AnyPublisher<Bool, Never> = getTestScore()
.map { [=10=] >= 70 }
.eraseToAnyPublisher()
scoreExceedsLimit
.filter { [=10=] == true }
.flatMap { _ in self.congratulate() }
.sink(receiveValue: { value in
print("first pipeline: \(value)")
})
.store(in: &subscriptions)
scoreExceedsLimit
.filter { [=10=] == false }
.flatMap { _ in self.getGPA() }
.sink(receiveValue: { value in
print("second pipeline: \(value)")
})
.store(in: &subscriptions)
}
}
let testing = Testing()