ReactiveSwift中运算符'<~'使用歧义问题求助
This is a classic type inference issue introduced by the stricter Swift 4.2 compiler in Xcode 10.3—your original closure has multiple code paths, and the compiler can't reliably infer the exact type being emitted by the Producer, which leads to ambiguity for the <~ binding operator (since it has several overloads). Here are two solid solutions that work without needing to upgrade your ReactiveSwift/ReactiveCocoa versions:
Solution 1: Explicitly Define Closure Types (Simplest Fix)
You don't need to split your binding at all—just give the compiler a hint by explicitly declaring the input type of your matches array and the return type of the closure. This removes all ambiguity:
// Replace MatchType with the actual type of elements in your matches array self.newMatchesTitleLabel.reactive.text <~ self.viewModel.newMatchesViewModel.data.producer.map { (matches: [MatchType]) -> String in let newMatchesCount = matches.filter({ !$0.hasViewedOnce }).count let newMatchesString = matches.count == 1 ? "New Match" : "New Matches" return newMatchesCount == 0 ? newMatchesString : "\(newMatchesString) (\(newMatchesCount))" }
By specifying [MatchType] as the input and String as the return, the compiler immediately knows this Producer emits strings, so it can pick the correct <~ overload for binding to a UILabel's text property.
Solution 2: Combine Your Split Bindings (If You Prefer Separated Logic)
If you want to keep your count and string logic split into separate properties, use combineLatest to merge their signals and generate the final title. First, make sure your class-level properties are MutableProperty instances (since you're binding to them):
// Define these as properties in your class let newMatchesCount = MutableProperty(0) let newMatchesString = MutableProperty("New Matches") // Bind your data producer to each property self.newMatchesCount <~ self.viewModel.newMatchesViewModel.data.producer.map { $0.filter({ !$0.hasViewedOnce }).count } self.newMatchesString <~ self.viewModel.newMatchesViewModel.data.producer.map { $0.count == 1 ? "New Match" : "New Matches" } // Merge the two signals and bind the final result to your label self.newMatchesTitleLabel.reactive.text <~ combineLatest(newMatchesCount.producer, newMatchesString.producer) .map { count, titleString in return count == 0 ? titleString : "\(titleString) (\(count))" }
combineLatest will emit a new tuple every time either property updates, and we map that tuple to your desired title string—clean, reactive, and resolves the type ambiguity.
Why This Happens
Xcode 10.3 uses Swift 4.2, which tightened up type inference rules compared to the Swift 4.0 in Xcode 10.1. Your original closure's multiple conditional branches made it hard for the compiler to pin down the exact output type of the Producer, leading it to consider multiple possible <~ overloads (hence the "ambiguous use" error). Both solutions above eliminate that ambiguity by explicitly defining types or splitting the logic into more type-clear steps.
内容的提问来源于stack exchange,提问作者Isuru

