0
0

ValueSemantics だと 何が嬉しいの

Posted at

続き

参照型で起こる副作用を 値型で防止する

  • 意図しない変更
  • 整合性の破壊

Swiftは 上記に対する 対処を値型で行う。

struct Person {
    var name: String
}

var person1 = Person(name: "Alice")
var person2 = person1
person2.name = "Bob"

print(person1.name) // Alice

Kotlinは 防御的コピー + イミュータブルクラス

data class Person(val name: String)
val person1 = Person(name = "Alice")
val person2 = person1.copy(name = "Bob")

println(person1.name) // Alice

防御的コピーと比べると 、いちいち全部作り直す手間がない分パフォーマンスが良い

さらに、Swiftの値型は、「複数の参照が同じデータを共有する場合、データはコピーされずにそのまま使用する。しかし、いずれかの参照がデータを変更しようとすると、その時点でコピーが作成され、変更はコピーに対して行われる。」 といった Copy on Write と呼ばれる仕組みがあって、配列のような大きくなりうるデータ に対する操作も パフォーマンスをよくしている。

var array1 = [1, 2, 3]
var array2 = array1 // 共有される
array2.append(4)    // この時点でコピーが作成される
print(array1)       // [1, 2, 3]
print(array2)       // [1, 2, 3, 4]

値型の変更を 参照型っぽくやる

inout 引数 を使うと もとの値型を変更することができる。が、Value Semanticsは壊れる可能性がある。

func modifyArray(_ array: inout [Int]) {
    array.append(4)
}

var array1 = [1, 2, 3]
modifyArray(&array1)
print(array1) // [1, 2, 3, 4]

メソッドの場合は mutating で inout と同じことができる

struct Person {
    var name: String
    
    mutating func changeName(to newName: String) {
        name = newName
    }
}

var person = Person(name: "Alice")
person.changeName(to: "Bob")
print(person.name) // Bob
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0