ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

Structureは継承できない

オブジェクトのシリアライズで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