LoginSignup
2
2

More than 5 years have passed since last update.

SwiftのArrayは値型でCoWなことの確認方法

Last updated at Posted at 2017-07-24

自分で確認しないと納得しない人向け

確かめる結論

① SwiftのArrayは値型
② 配列自体を他の変数に代入した時には配列の内容のコピーが走らない
③ 配列の内容が変更された時に配列の内容がコピーされる

※②、③はいわゆるCopy-on-Write(CoW)のこと

確認方法

① SwiftのArrayは値型

var a = [1,2,3]
var b = a
b[1] = 0
とすると、bは[1,0,3]となるが、aは[1,2,3]のままなので値型である。
(もしも、参照型であればaも[1,0,3]となるので)


  1> var a = [1,2,3]
a: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  2> var b = a
b: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  3> b[1] = 0
  4> a
$R0: [Int] = 3 values {
  [0] = 1
  [1] = 2   // 元のaはそのまま
  [2] = 3
}
  5> b
$R1: [Int] = 3 values {
  [0] = 1
  [1] = 0   // bだけ変わった
  [2] = 3
} 

② 配列自体を他の変数に代入した時には配列の内容のコピーが走らない

配列を代入した段階ではa,b共に同じ値が格納されているので、実体が一つで十分であるから。
var a = [1,2,3]
var b = a
とすると、a,bともに0x00000001001004f0と同じメモリ番地を指しているため内容自体はコピーされていない。

  1> var a = [1,2,3]
a: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  2> Unmanaged.passUnretained(a as AnyObject).toOpaque()
$R0: UnsafeMutableRawPointer = {
  _rawValue = 0x00000001001004f0
}
  3> var b = a 
b: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  4> Unmanaged.passUnretained(a as AnyObject).toOpaque()
$R1: UnsafeMutableRawPointer = {
  _rawValue = 0x00000001004000f0    // aと同じメモリの番地
}

③ 配列の内容が変更された時に配列の内容がコピーされる

上記②の続きで、
b[1] = 1
とした瞬間にコピーされる。
コピーされたことは変数bのアドレスが変更されていることによりわかる。

  5> b[1] = 8
  6> a
$R2: [Int] = 3 values {
  [0] = 1
  [1] = 2
  [2] = 3
}
  7> b
$R3: [Int] = 3 values {
  [0] = 1
  [1] = 8
  [2] = 3
}
  8> Unmanaged.passUnretained(a as AnyObject).toOpaque()
$R4: UnsafeMutableRawPointer = {
  _rawValue = 0x00000001001004f0
}
  9> Unmanaged.passUnretained(b as AnyObject).toOpaque() 
$R6: UnsafeMutableRawPointer = {
  _rawValue = 0x0000000100301400 // 違うメモリの番地を指している
}

 補足

  • 定数となるletは他の変数に代入してもそもそも内容をコピーする必要がなく例として面白くないのでvarのみを考えてる。
  • コンパイラはApple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
2
2
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
2
2