質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

2229閲覧

Go言語でスライスの値を外部から上書きできてしまう

退会済みユーザー

退会済みユーザー

総合スコア0

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2017/07/21 04:00

以下のようにパッケージ内の値を返すメソッドを作成したのですが、スライスの値だけパッケージ外からでも元の値が上書きできてしまいます。

他の型同様、元のスライスの値を上書きされないようにする方法はありますでしょうか?また他にも今回のように上書きできてしまう型がありましたら教えて下さい。

宜しくお願いします。

Go

1package main 2 3import ( 4 "fmt" 5 "./hoge" 6) 7 8func main() { 9 // 元の値 10 a := hoge.Get() 11 fmt.Println("string: " + a.Str + " slice: " + a.Slice[0]) 12 13 // 値を変更 14 a.Str = "NG" 15 a.Slice[0] = "NG" 16 fmt.Println("string: " + a.Str + " slice: " + a.Slice[0]) 17 18 // スライスだけ値が上書きされている 19 fmt.Println("string: " + hoge.Get().Str + " slice: " + hoge.Get().Slice[0]) 20} 21 22 23package hoge 24 25var h = Hoge{Str: "OK", Slice: []string{"OK"}} 26 27type Hoge struct { 28 Str string 29 Slice []string 30} 31 32func Get() Hoge { 33 return h 34}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

スライスはリファレンスなので更新できてしまいます。また golang には const の様な物がないので Get でコピーを返すくらいしか方法はないと思います。

go

1func Get() Hoge { 2 var hc Hoge 3 hc.Str = h.Str 4 hc.Slice = make([]string, len(h.Slice)) 5 copy(hc.Slice, h.Slice) 6 return hc 7}

追記

どうしても隠ぺいしたいなら、以下の様に全て非公開にすべきです。

go

1package hoge 2 3var h = Hoge{str: "OK", slice: []string{"OK"}} 4 5type Hoge struct { 6 str string 7 slice []string 8} 9 10func Get() *Hoge { 11 return &h 12} 13 14func (h *Hoge) Str() string { 15 return h.str 16} 17 18type mySlice struct { 19 slice []string 20} 21 22func (h *Hoge) Slice() *mySlice { 23 return &mySlice{h.slice} 24} 25 26func (ms mySlice) Get(i int) string { 27 return ms.slice[i] 28} 29 30func (ms mySlice) Len() int { 31 return len(ms.slice) 32}

この場合、以下の様なアクセスになります。

go

1package main 2 3import ( 4 "fmt" 5 6 "./hoge" 7) 8 9func main() { 10 // 元の値 11 a := hoge.Get() 12 fmt.Println("string: " + a.Str() + " slice: " + a.Slice().Get(0)) 13 14 // 値を変更 15 16 // 変更できない 17 // a.Str() = "NG" 18 19 // これもだめ 20 // a.Slice()[0] = "NG" 21 fmt.Println("string: " + a.Str() + " slice: " + a.Slice().Get(0)) 22 23 // スライスだけ値が上書きされている 24 fmt.Println("string: " + hoge.Get().Str() + " slice: " + hoge.Get().Slice().Get(0)) 25}

投稿2017/07/21 09:49

編集2017/07/21 10:03
mattn

総合スコア5030

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/21 22:38

なるほどリファレンスでしたか。気がつかず延々ハマってました。。ソース参考になります。回答どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問