【问题标题】:How to mock inheritance in a swift struct如何在 swift 结构中模拟继承
【发布时间】:2021-01-14 12:49:40
【问题描述】:

我正在设计我的应用模型,并希望有两个结构以某种方式“继承”。假设,这两个结构是

struct Book {
    
    var author: String
    var publisher: String
    
    var isHardcover: Bool
}

struct Comic {
    
    var author: String
    var publisher: String
    
    var superhero: String
}

我不确定如何以最佳方式设计它。我想要

  • 让结构是可变的(从设计的角度来看,这意味着我可能想要更改字段的类型或稍后添加/删除另一个字段)并且如果它同时影响这两个结构,则两个结构都应该反映该更改
  • 能够将两个结构放入一个集合中

此外,实现公共字段的结构的数量是有限且已知的,因此枚举也是一种选择。

我想出了几个解决方案,但似乎没有一个完全令人满意。

  1. 将结构体交换为类并使用继承;这确实有效,但根据苹果的指导方针,我的用例完全适合结构之一

  2. 创建一个“通用”结构,并让这个通用结构成为两个结构的成员,即

struct Common {
    var author: String
    var publisher: String
}
struct Book {
    var common: Common

    var isHardcover: Bool
}
struct Comic {
    var common: Common

    var superhero: String
}

缺点是我总是要打电话给comic.common.author,这样可读性差,信息量少,但似乎是迄今为止最好的解决方案

  1. 在我定义实现结构必须符合变量的地方使用协议继承;这里的缺点是它不是真正可变的

  2. 使用具有存储属性的枚举

enum Readable {
    case book(_ book: Book)
    case comic(_ comic: Comic)
}

这也有点难看,不允许我简单地调用readable.author(除非我在枚举中实现该函数,但这似乎并不好,因为我需要为每个小变量提供详细的开关语句)

我要问的问题是,如果有的话,我应该选择以上哪一项?我有什么遗漏吗?

【问题讨论】:

  • 你应该只使用一个类。

标签: swift struct


【解决方案1】:

在我定义实现结构必须符合变量的地方使用协议继承;这里的缺点是它不是真正可变的

我会选择这个解决方案。我不确定你为什么说协议不是真正可变的。

你可以定义一个协议Book

protocol Book {
    var author: String { get set }
    var publisher: String { get set }
}

然后将它用于所有书籍“子类型”

struct Novel: Book {
    var author: String
    var publisher: String
    
    var isHardcover: Bool
}

struct Comic: Book {
    var author: String
    var publisher: String
    
    var superhero: String
}

此时您可以将 Avery 书放入收藏夹

let someComic = Comic(author: "author", publisher: "publisher", superhero: "superhero")
var someNovel = Novel(author: "author", publisher: "publisher", isHardcover: true)

let books: [Book] = [someComic, someNovel] // this works fine

并改变单个实例(请注意,由于结构是值类型,这不会更新数组中的值。如果需要,您需要手动替换为更新的值或使用类。 )

var books: [Book] = // ...

var updatedBook: Book = books.first!
updatedBook.publisher = "another publisher"

// Update the collection with the updated book.
books[0] = updatedBook

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 2011-04-22
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    相关资源
    最近更新 更多