オブジェクトのシリアライズでStructureを定義するとjsonなどに変換しやすくなる。
既存ソフトの置換えをしていて次の様な流れで処理しようとしている。
Export
Object(Class) -> Struct -> JSON
Import
JSON -> Struct -> Object(Class)
Classは継承したものもあって、
struct AContainer {
var name: String
}
struct BContainer: AContainer {
var greeting: String
}
という感じにしたら inheritance from non-protocol type 'AContainer' というエラーがでた。
Structures and classes in Swift have many things in common. Both can:
Conform to protocols to provide standard functionality of a certain kind
Classes have additional capabilities that structures don’t have:
Inheritance enables one class to inherit the characteristics of another
プロトコルの適用はできるけど継承はクラスじゃなきゃできないというとだっった。
docs.swift.org
AContainerの中身をBContainerにコピーしなければならない。
AContainerで増減があった場合に忘れずにBContainerも変更しなければならない。
struct AContainer {
var name: String
}
struct BContainer {
var name: String
var greeting: String
}
ファイル生成スクリプト使ってやった方が間違いないかな…と思ってやってたら..
Relationの場合
sturct Root {
var chidren: [AContainer]
}
ってやりたいのにBContainerはAContainerを継承していないので含めることができない。
AもBも包括するStructureを作ってどちらの型か判別できるpropertyを使わないといけない。
class A {
init(){
name = String(describing: type(of: self))
}
var name: String
}
class B: A {
override init(){
greeting = "Hello"
}
var greeting: String
}
struct ABContainer {
var type: String
var name: String
var greeting: String?
}
struct Root {
var children: [ABContainer] = []
mutating func addAB(_ obj: A) {
if let b = obj as? B {
var container = ABContainer(type: "B", name: b.name, greeting: b.greeting)
children.append(container)
} else{
var container = ABContainer(type: "A", name: obj.name)
children.append(container)
}
}
}
let a = A()
let b = B()
var r = Root()
r.addAB(a)
r.addAB(b)
print(r) // -> Root(children: [__lldb_expr_87.ABContainer(type: "A", name: "A", greeting: nil), __lldb_expr_87.ABContainer(type: "B", name: "B", greeting: Optional("Hello"))])
ところでSubscriptsというのが目に入った。
内部データへのアクセスに関するものらしいけどまた改めて調べることとしよう。
docs.swift.org
参考
zenn.dev