【问题标题】:Using JSON Encoder with a computed variable of type Codable将 JSON 编码器与 Codable 类型的计算变量一起使用
【发布时间】:2018-11-24 03:17:27
【问题描述】:

凭借我的新手 swift 技能,我正在努力找出正确的 swift 语法来让这个游乐场工作。根据我尝试解决它的方式,我要么得到 ​​p>

不能使用类型为“(Encodable)”的参数列表调用“encode”

这类似于这个问题Using JSON Encoder to encode a variable with Codable as type 中解决的问题,或者我得到了

' (T) -> ()' 要求 'Encodable' 符合 'Encodable'

非常感谢有解释的解决方案

编辑 为了提供更多上下文,我在这里尝试实现的模式是用于中间件路由器。根据应用程序中的操作,路由器将构建网络请求。 codableParam 的目的是为用例提供一致的结构。因此,所有情况都将返回 nil 或 Codable 类型。

struct unityAuthenticationRequest: Codable {
    var username : String
    var password : String
}

enum test  {
    case volume
    case num2
    case num3

    var codableParam: Encodable? {
        switch self {
        case .volume:
            return unityAuthenticationRequest(username: "uname", password: "pwrods")
        default:
            return nil
        }
    }
}

func saveObject<T:Encodable>(_ object: T) {
    let data = try? JSONEncoder().encode(object)
}

func dx<T: Codable>(fx: T) {
    let datax = try? JSONEncoder().encode(fx)
}

let r = test.volume
saveObject(r.codableParam)

【问题讨论】:

  • 你想要达到什么目的?你的例子似乎很做作,没有解释你的代码应该做什么。您不能返回 Encodable 并将其作为输入提供给 saveObject,因为 Encodable 不能用作具体类型,如果您检查有问题的行上的两个错误,错误消息实际上会告诉您。跨度>
  • 根据要求编辑和添加意图
  • 我正在考虑的一个选项是让 codableParam 函数变形为 codableData - 在函数内执行编码 - 但这似乎是一种解决方法
  • 现在我更加困惑了。如果您尝试创建URLRequests,为什么要返回Codable?为什么要将URLRequest 编码为 JSON?在将URLRequest 编码为 JSON 后,您打算如何执行它?顺便说一句,您应该遵守 Swift 命名约定,类型名称是 UpperCamelCase,所以 TestUnityAuthenticationRequest 是合适的。
  • 我以medium.com/@AladinWay/… 为例 - 这将向您展示更广泛的背景。在此示例中,它使用 JSONSerialisation,但我想了解 Codable 是否是更好的选择。

标签: swift generics codable encodable


【解决方案1】:

错误消息几乎可以告诉您发生了什么:

Fatal error: Optional<Encodable> does not conform to Encodable
  because Encodable does not conform to itself.
  You must use a concrete type to encode or decode.:
    file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/Codable.swift, line 3960

这很容易修复,只需像这样更改您的第一行:

var codableParam: unityAuthenticationRequest? {
    switch self {
    case .volume:
        return unityAuthenticationRequest(username: "uname", password: "pwrods")
    default:
        return nil
    }
}

现在您的参数确实有一个具体的类型,并且通过最小的语法更改满足了要求。

我仍然很难弄清楚这种类型的代码如何以最易于理解的方式传递您的意图,但我们必须更多地了解您的意图才能对其进行改进。

【讨论】:

  • Thx @Patru - 我确实考虑过这一点,但因为不同的情况会返回不同的结构,所以我没有进展(现在已经在主要问题中澄清了)。是否可以对类型进行子类化并使用基类作为类型(同样,这个建议的快速知识有限)
  • 你的类必须是具体的,此时它不能是protocol。您应该能够从公共基类(实现Codable)派生不同的子类,并让您的enum 方法返回基类。但是,如果没有一些更具体的示例,我无法完全看出关联值是否会产生更好的代码。
猜你喜欢
  • 2017-12-16
  • 1970-01-01
  • 2014-04-21
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多