【问题标题】:Binary operator '<^>' cannot be applied to operands of type二元运算符“<^>”不能应用于类型的操作数
【发布时间】:2019-11-17 21:32:40
【问题描述】:

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

二元运算符''不能应用于'(())类型的操作数 -> VoiceMailNumberResponse'和'解码<_>'

这是我的代码:

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"
    }
}

在线出现错误:"&lt;^&gt; json &lt;|? "name"

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

【问题讨论】:

    标签: ios swift xcode11.2 argo


    【解决方案1】:

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

    由于 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 一起使用,这似乎是行为上的改变。

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

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

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

    • 这是语言/编译器更改,因此 ArgoCurryRunes 可能需要更新,您应该报告(版本历史表明之前已经解决了歧义);

    • “功能”,在这种情况下,您应该前往 feedbackassistant.apple.com 并提交错误报告;或

    • 别的东西

    您可能还想考虑使用 Xcode 9 中引入的 Swift's Decodable 来解码 JSON,以替代使用这些第三方包。

    HTH

    【讨论】:

    • 除了通过中间变量和手动类型声明来选择init,您还可以使用所有选择器以完整形式指定initcurry(VoiceMailNumberResponse.init(name:value:))
    • @user28434 – 好收获!应该记得,我会编辑答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2019-02-13
    • 2019-08-23
    • 2016-09-20
    相关资源
    最近更新 更多