二元运算符“<^>”不能应用于类型的操作数

Binary operator '<^>' cannot be applied to operands of type

我实现了以下代码以使用 Argo 框架,一直工作到 Xcode 11.2.1更新。当我更新 Xcode 版本时出现以下错误:

Binary operator '<^>' cannot be applied to operands of type '(()) -> VoiceMailNumberResponse' and 'Decoded<_?>'

这是我的代码:

struct VoiceMailNumberResponse{
    var name: String?
    var value: String?
}

extension VoiceMailNumberResponse: Argo.Decodable {
    static func decode(_ json: JSON) -> Decoded<VoiceMailNumberResponse> {
        let voiceMailNumberResponse = curry(VoiceMailNumberResponse.init)
        return voiceMailNumberResponse
            <^> json <|?  "name"
            <*> json <|?  "value"
    }
}

在线出现错误:"<^> json <|? "name"

此外,我使用 ArgoCurryRunes 来解析 JSON.

注意:此答案仅基于您的代码示例,尚未经过测试。

由于 VoiceMailNumberResponse 的两个属性都是可选的,因此 Xcode 10.1/Swift 4.2(测试的版本)产生两个 init 方法:

init()
init(name: String?, value: String?)

如果两者都不是,或者只有一个,则 属性 是可选的,仅生成第二个 init。从问题看来 Xcode 11.2.1/Swift 5.1 的行为方式相同。

报错信息中的类型:

(()) -> VoiceMailNumberResponse

表示编译器选择了init()传递给curry,而代码期望传递init(name: String?, value: String?)

由于代码显然适用于以前的一些 Xcode/Swift 这似乎是行为上的变化。

这可能是对语言 and/or 编译器的更改或 "feature"。您可以通过包含参数名称来明确指定要使用的 init 来解决它,例如类似于:

...
let voiceMailNumberResponse = curry(VoiceMailNumberResponse.init(name:value:))
...

也就是说最好弄清楚是否:

  • 这是一个 language/compiler 变化,因此 ArgoCurryRunes 可能需要更新,您应该报告(版本历史记录表明之前已经解决了歧义);

  • a "feature",在这种情况下,您应该前往 feedbackassistant.apple.com 并提交错误报告;或

  • 其他

您可能还想看看使用 Xcode 9 中引入的 Swift's Decodable 来解码 JSON 作为使用这些第三方包的替代方法。

HTH