如何映射到 Combine 中的类型?

How can I map to a type in Combine?

我有很多页面供用户输入信息。他们可以输入带有日期、数字或文本的字段。

我正在尝试接收 Combine 中的所有更改并将它们的输出作为 Encodable 以便我可以轻松地将结果上传到网络。

A StringEncodable,所以我认为这很容易,但我无法让它在 Combine 中工作。我收到编译器错误:

Cannot convert return expression of type 'Publishers.Map<Published.Publisher, Encodable>' to return type 'Published.Publisher'

有一个解决方法,我在 SampleTextHandler 中添加另一个 属性,即 @Published var userTextEncodable: Encodable,但这不是我想要做的。

import Combine

protocol FieldResponseModifying {
    var id: String { get }
    var output: Published<Encodable>.Publisher { get }
}


struct SampleTextWrapper {
    var output: Published<Encodable>.Publisher {
        // Cannot convert return expression of type 'Publishers.Map<Published<String>.Publisher, Encodable>' to return type 'Published<Encodable>.Publisher'
        handler.$userTextOutput.map { [=10=] as Encodable}
    }
    
    let id = UUID().uuidString
    let handler = SampleTextHandler()
}

class SampleTextHandler {
   @Published var userTextOutput = ""
    init () { }
}

Combine 大量使用泛型。例如,您使用 map 返回的类型是 Publishers.Map<Published<Value>.Publisher, Encodable>。所以你可以这样声明你的属性:

var output: Publishers.Map<Published<Encodable>.Publisher, Encodable> {
    handler.$userTextOutput.map { [=10=] as Encodable}
}

但现在您的 属性 的类型在很大程度上取决于它的实现方式。如果更改实现,则必须更改类型。

相反,您几乎肯定应该使用“类型橡皮擦”AnyPublisher,如下所示:

var output: AnyPublisher<Encodable, Never> {
    handler.$userTextOutput
        .map { [=11=] as Encodable }
        .eraseToAnyPublisher()
}

由于您使用了 Encodable 存在主义,您可能会 运行 进入另一个问题。当你点击它时,你会想要 post 另一个问题。