ひよっこGolangerです。まだGoについて理解しきれてないです。先日もふとオブジェクトの実体のslice型は、appendするとオブジェクトのコピーがappendされるのでは・・・と思ったので確かめるべくサンプルコードを書いた。
package main
import (
"fmt"
)
type User struct {
Name string
}
func main() {
pointerArray()
objectArray()
}
func pointerArray() {
// Userポインタのslice
var users []*User
// Userポインタをuser1,user2へ入れる
user1 := &User{
Name: "user1",
}
user2 := &User{
Name: "user2",
}
// Userポインタをappend
users = append(users, user1)
users = append(users, user2)
// slice経由でNameを変更する
users[0].Name = "user1+"
users[1].Name = "user2+"
fmt.Printf("[pointerArray]\n" )
fmt.Printf("user1.Name:%s\n", user1.Name)
fmt.Printf("user2.Name:%s\n", user2.Name)
fmt.Printf("users[0].Name:%s\n", users[0].Name)
fmt.Printf("users[1].Name:%s\n", users[1].Name)
}
func objectArray() {
// User実体のslice
var users []User
// User実体をuser1,user2へ入れる
user1 := User{
Name: "user1",
}
user2 := User{
Name: "user2",
}
// User実体をappend
users = append(users, user1)
users = append(users, user2)
// slice経由でNameを変更する
users[0].Name = "user1+"
users[1].Name = "user2+"
fmt.Printf("[objectArray]\n" )
fmt.Printf("user1.Name:%s\n", user1.Name)
fmt.Printf("user2.Name:%s\n", user2.Name)
fmt.Printf("users[0].Name:%s\n", users[0].Name)
fmt.Printf("users[1].Name:%s\n", users[1].Name)
}
出力結果
[pointerArray]
user1.Name:user1+
user2.Name:user2+
users[0].Name:user1+
users[1].Name:user2+
[objectArray]
user1.Name:user1
user2.Name:user2
users[0].Name:user1+
users[1].Name:user2+
うう、やっぱり[]Userの方は、値が変わらない。つまりオブジェクトがコピーされてる・・・
オブジェクトが大きい場合、コピーは無駄なのでポインタをsliceで持ったほうが良いだろう。それにたいていの言語では、配列にオブジェクトを追加する時は、参照を追加するのでそれに合わせたほうが混乱がないだろう。
ちなみにAWSのライブラリのコード見ると、やっぱりポインタのsliceを使うようにしている。