您可以“扩展”(即添加额外的初始化逻辑)Codable 对象的自动生成构造函数吗?

2023-12-08

当你实施Codable对于一个对象,编译器可以自动为您生成一个构造函数。然而,只有当您没有编写自己接受解码器的初始化程序时,它才会执行此操作。

也就是说,我们有一个大约 50 的对象let从解码器设置的属性,但我们还有五个基于这些属性的计算属性let特性。

从技术上讲,如果我们可以在初始化程序中计算它们,那么在解码器设置其他 50 个之后,我们可以简单地将结果存储在let它们自己的变量,完全消除了对计算属性的需要。

问题是,如前所述,如果您实现自己的初始化程序,编译器不会为您自动生成初始化程序,因此您不仅要初始化“计算”值,而且还要初始化“计算”值。all values.

那么有没有一种方法可以让您将自己插入到初始化/解码过程中,而不必自己完全重写初始化程序呢?


您正在寻找的内容与委托模式类似,解码器通知其委托已完成解码。遗憾的是,它还没有添加到 Swift 中。我能想到的最接近的是使用继承,这样 Swift 就可以自动生成这 50 个解码器let在基类中,您可以在子类中初始化计算属性。例如:

class A: Decodable {
    let firstName: String
    let lastName: String
}

class B: A {
    private var _fullName: String! = nil
    var fullName: String { return _fullName }

    required init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        _fullName = firstName + " " + lastName
    }
}

在 A 类中定义 50 个属性,并将所有计算属性保留在 B 类中。


或者根据您的建议,您也可以使用lazy var:

struct Model: Decodable {
    let firstName: String
    let lastName: String

    // private(set) so users cannot change value of the
    // pre-computed property
    lazy private(set) var fullName = self.firstName + " " + self.lastName
}

// But you can't use a let here, since calling fullName
// for the first time will mutate the struct
var model = try JSONDecoder().decode(Model.self, from: json)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

您可以“扩展”(即添加额外的初始化逻辑)Codable 对象的自动生成构造函数吗? 的相关文章

  • 在C++中初始化静态指针

    我有一个带有静态成员的类 它是一个指针 如下所示 动画 h class Animation public Animation static QString m 动画 cpp include animation h QString Anima
  • 反对“initialize()”方法而不是构造函数的争论

    我目前负责查找代码库中的所有不良做法 并说服我的同事修复有问题的代码 在我的探索过程中 我注意到这里很多人都使用以下模式 class Foo public Foo Do nothing here bool initialize Do all
  • Swift 中 flatMap 和 CompactMap 的区别

    似乎在斯威夫特 4 1 flatMap已弃用 不过有一个新的方法斯威夫特 4 1 compactMap哪个在做同样的事情 和flatMap您可以转换集合中的每个对象 然后删除任何为零的项目 喜欢平面地图 let array 1 2 nil
  • 为什么在 C++ 中将变量定义和初始化分开?

    我目前正在研究一些相当古老的 C 代码 经常发现类似的东西 int i i 42 or Object someObject NULL someObject new Object or even Object someObject someO
  • F# 中的数组初始化

    如何根据给定的记录类型在 F 中创建和初始化数组 假设我想创建一个包含 100 个 record1 记录的数组 e g type record1 value1 string value2 string let myArray Array i
  • Rails 是否为 rake 任务运行初始化程序?

    当我运行 rake 任务时 是否执行配置 初始化程序中的脚本 如果你的 rake 任务取决于 environment 即 您像这样声明您的任务 task my task gt environment do end
  • 未初始化变量的值是如何确定的?

    给定一个程序 int main short myVariableName1 stores from 32768 to 32767 short int myVariableName2 stores from 32768 to 32767 si
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • 使用空的weak_ptr作为参数调用map::count安全吗?

    打电话安全吗map count http www cplusplus com reference map map count on an 未初始化因此为空weak ptr http en cppreference com w cpp mem
  • 使用父级的 init 创建一个类的子类 - 来自另一个类

    编辑 这里的投票综合症很糟糕 我问了一个问题 我认为这表明我做了功课 并寻求建议 被赞成的答案意味着要进行编译时警告 而我自己的 可能是最干净的 OOP 方式没有引起任何兴趣 简要概述以了解为什么我需要这个以及我尝试做什么 我正在编写一个实
  • 静态成员声明为 const 但初始化为 constexpr

    考虑一个具有常量成员的类 class foo public const static int N foo N需要初始化 constexpr int foo N 5 并注意如何使用constexpr限定符而不是const这里似乎是一个错误 但
  • 在 Swift 4 中,如何删除基于块的 KVO 观察者?

    如果我像这样存储观察者 let observer NSKeyValueObservation foo observe value options new foo change in print change newValue 如何删除 禁用
  • 在 Swift 中监听 stdin

    目前 我正在尝试在我的 swift 应用程序中监听来自命令行的用户输入 我知道readLine 方法 但它并不真正符合我的需求 我想监听在命令行上插入的数据 就像用户在终端内按下 向上键 一样 类似于 Node js 中可以完成的事情 st
  • std::queue 初始化为 NULL

    是否可以初始化一个C std queue with a NULL像其他变量一样的值 像这样 HANDLE variable NULL class Test i e std queue
  • C 中的 if 语句和垃圾值[重复]

    这个问题在这里已经有答案了 我是 C 编程新手 我知道这是一个非常简单的问题 但我需要一些建议 我正在练习控制结构if statement 我遇到过一个例子 这是代码 include
  • 与 UIActivityViewController 共享 PDF 文件

    我正在尝试使用共享 PDF 文件UIActivityViewController但是当我按下按钮时 我没有共享文件的选项 我怎样才能显示这些选项 https i stack imgur com ywDQw jpg https i stack
  • AVCaptureMetadataOutputObjectsDelegate 在 swift 4 中未针对 QR 扫描仪调用

    我正在 iOS 上开发 QR 码扫描仪应用程序 我正在获取输出AVCaptureOutput在委托方法上captureOutput didOutputMetadataObjects fromConnection 它在 swift 3 上完美
  • 如何在 swift 4 中进行两个并发 API 调用

    预先感谢您的帮助 我有两个 API 调用 都是并发的 任何调用都可以先成功 我不想按顺序调用 在两个调用成功后 我必须停止我的活动指示器并重新加载我的 tableView 这是我的代码 但我不知道这是正确的方法 也不知道如何重新加载我的 t
  • 空检查时可能未初始化错误

    我正在检查变量是否已初始化 但此时 netbeans 给了我variable reader might not have been initialized警告 我该如何解决 抑制这个问题 这是我的代码 摘要 final Reader rea
  • 如何在不运行 PostgreSQL 服务器的情况下初始化 PostgreSQL 数据库

    在初始化脚本中 我想初始化 PostgreSQL 目录 但在此阶段不需要 也不希望 正在运行的 PostgreSQL 服务器 如果我只是创建集群 作为用户postgres initdb D 但是 我还需要创建 PostgreSQL 角色 创

随机推荐