Successfully reported this slideshow.
Your SlideShare is downloading. ×

Go言語のスライスを理解しよう

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 60 Ad

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement

Similar to Go言語のスライスを理解しよう (20)

Advertisement

Recently uploaded (20)

Go言語のスライスを理解しよう

  1. 1. Go言語のスライスを 理解しよう 2012/08/25 GDG Kobe
  2. 2. 自己紹介 • 河本 泰孝 @yasi_life → @kwmt27 • 私とGo言語との関わり • 2011年のDevQuizで初めて触った • 2012年1月のGo言語勉強会に参加 • 2012年4月の東海GTUGさんのGAE 勉強会でGoを使った
  3. 3. 自己紹介 • 最近では公式サイトの • Writing Web Applications • Go Slices を翻訳してみたり。 https://github.com/ kwmt/golangwiki/wiki
  4. 4. 自己紹介 ということで、 • 1月のGo言語勉強会では スライスまで出来なくて、 • 自分でスライスについて翻訳してみた ので 公式サイトのGo Slicesを元に発表させて 頂きます。
  5. 5. もくじ
  6. 6. もくじ 1.かるく復習 2.Go言語の配列とは? 3.スライスとは? (1)特徴 (2)内部構造 (3)拡張する (4)削除する
  7. 7. 進め方 説明しながら、実際に動きを確かめるデモを していきたいと思います。 もし可能なら下記のサイトで動かせるので一 緒に動かして行きましょう。 http://play.golang.org/ でもそこまでガッツリやって頂く時間がない かもしれません。半ハンズオン的な感じです す。 ソース場所:https://github.com/kwmt/
  8. 8. 1.かるく復習 変数宣言のいろいろ var a int = 1 // int型 a := 1 標準出力するには import “fmt” fmt.Printf(“a=%d¥n”, a) デモ slice_0.go
  9. 9. 2.Go言語の配列とは?
  10. 10. 配列の定義方法 長さ(length) と要素の型を指定 var a [4]int
  11. 11. 配列の定義方法 長さ(length) と要素の型を指定 var a [4]int 長さ (length)
  12. 12. 配列の定義方法 長さ(length) と要素の型を指定 var a [4]int 長さ 要素の型 (length)
  13. 13. 配列の特徴 a[n]はn番目の要素にアクセス可能 //配列宣言 var a [4]int //0番目の要素に1を代入 a[0] = 1 //変数iを宣言してa[0]をiに代入 i := a[0] // 表示すると // i = 1 デモ slice_1.go
  14. 14. 配列の特徴 明示的な初期化は不要 (自動的に0で初期化されています) 前ページの例の0番目の要素以外は 値0となっています。 // a[0]==1,a[1]==0,a[2]==0,a[3]==0 デモ slice_1.go
  15. 15. 配列の特徴 配列変数は配列全体を表しています。 つまりC言語のように、先頭の配列要素へ のポインタではありません。 イメージ
  16. 16. 配列の特徴 配列リテラルの書き方 ・要素数を指定する b := [2]string{“Penn”,”Teller”} ・要素数を指定しない (コンパイラに数えさせる) b := [...]string{“Penn”,”Teller”} デモ slice_1.go
  17. 17. 3.スライスとは?
  18. 18. スライスの定義方法 長さ(length) と要素の型を指定 var a []int 長さ (length) 要素の型
  19. 19. スライスの定義方法 長さ(length) と要素の型を指定 var a []int 長さ (length) 要素の型
  20. 20. (1)スライスの特徴 スライスリテラルの書き方 letters := []string{“a”,”b”,”c”,”d”} 要素数の指定以外は、 配列リテラルの書き方と同じ
  21. 21. (1)スライスの特徴 組み込み関数 makeを 使ってスライスを作成できる。
  22. 22. (1)スライスの特徴 make関数とは make関数の書式 func make([]T, len, cap) []T T:要素の型 len:長さ(length) cap:容量(capacity)(オプション)
  23. 23. (1)スライスの特徴 make関数とは make関数は、スライス型のオブジェク トを確保し、初期化する。 1番目の引数の型と同じ型を返す。 ポインタを返すわけではない。 func make([]T, len, cap) []T
  24. 24. (1)スライスの特徴 make関数を使って スライスを作成する例 var s []byte s = make([]byte, 5, 5) // s=[0 0 0 0 0] // sの型=[]uint8 デモ slice_2.go
  25. 25. (1)スライスの特徴 容量(capacity)は省略できる var s []byte s = make([]byte, 5, 5) 次のように簡略化できる s := make([]byte, 5) ※容量を省略すると、長さ=容量となる デモ slice_2.go
  26. 26. (1)スライスの特徴 スライスの長さ(length)と 容量(capacity)を 調べるには、組み込み関数のlenと capを使用する。 len(s) // == 5 cap(s) // == 5 デモ slice_2.go
  27. 27. (1)スライスの特徴 スライスのゼロ 初期化さてないスライスの値:nil スライス==nilならば、   len,cap関数は0を返す デモ slice_2.go
  28. 28. (1)スライスの特徴 re-slice 再スライス化可能 b := []byte{‘g’,’o’,’l’,’a’,‘n’,’g’} c := b[1:4] // c=[]byte{’o’,’l’,’a’} // スライスcはスライスbと同じメモリ領域 デモ slice_2.go
  29. 29. (1)スライスの特徴 re-slice b[1:4] デモ slice_2.go
  30. 30. (1)スライスの特徴 re-slice b[1:4] デモ slice_2.go
  31. 31. (1)スライスの特徴 re-slice b[1:4] これら2つの数字は 省略可能 デモ slice_2.go
  32. 32. (1)スライスの特徴 re-slice b[:] b[:2] b[2:] デモ slice_2.go
  33. 33. (1)スライスの特徴 re-slice b[:] ==b b[:2] b[2:] デモ slice_2.go
  34. 34. (1)スライスの特徴 re-slice b[:] ==b b[:2] ==[]byte{‘g’,’o’} b[2:] デモ slice_2.go
  35. 35. (1)スライスの特徴 re-slice b[:] ==b b[:2] ==[]byte{‘g’,’o’} b[2:] ==[]byte{‘l’,’a’,’n’,’g’} デモ slice_2.go
  36. 36. (1)スライスの特徴 re-slice 自分のコードで、s[:len(s)] と再スライスしてたよ、、、へへ。 デモ slice_2.go
  37. 37. (1)スライスの特徴 re-slice 配列からスライスを作る デモ slice_2.go
  38. 38. (1)スライスの特徴 re-slice 配列からスライスを作る x := [3]string{"Лайка", "Белка", "Стрелка"} s := x[:] // スライスsはxの記憶領域を参照 デモ slice_2.go
  39. 39. (2)スライスの内部構造 スライスは、配列内の連続した領域への イメージ 参照であり、以下の3つから構成される。 ๏配列へのポインタ ๏セグメントの長さ(length) ๏容量(capacity) (セグメントの最大の長さ)
  40. 40. (2)スライスの内部構造 s := make([]byte,5) イメージ デモ slice_3.go
  41. 41. (2)スライスの内部構造 s = s[2:4] イメージ デモ slice_3.go
  42. 42. (2)スライスの内部構造 再スライスされた要素を変更すると、 元のスライスの要素も変更される。 d := []byte{'r', 'o', 'a', 'd'} e := d[2:] // e == []byte{'a', 'd'} e[1] == 'm' // e == []byte{'a', 'm'} // d := []byte{'r', 'o', 'a', 'm'} デモ slice_3.go
  43. 43. (2)スライスの内部構造 len < cap の場合、lenをcapまで拡張できる s = s[:cap(s)] イメージ デモ slice_3.go
  44. 44. (2)スライスの内部構造 容量を超えて拡張できない。
  45. 45. (2)スライスの内部構造 容量を超えて拡張できない。 容量を増やせば、拡張できる。
  46. 46. (3)スライスを拡張する copyとappend関数 容量(capacity)を増やすには、 1.新しく大きな容量のスライスを作成 2.その新しいスライスに元のスライスの 内容をコピーする
  47. 47. (3)スライスを拡張する copyとappend関数 s := make([]byte, 5) t := make([]byte, len(s), (cap(s)+1)*2) for i := range s { t[i] = s[i] } s = t デモ slice_4.go
  48. 48. (3)スライスを拡張する copyとappend関数 s := make([]byte, 5) t := make([]byte, len(s), (cap(s)+1)*2) for i := range s { t[i] = s[i] } s = t デモ slice_4.go
  49. 49. (3)スライスを拡張する copyとappend関数 copy関数を使って次のように書ける s := make([]byte, 5) t := make([]byte, len(s), (cap(s)+1)*2) copy(t, s) s = t デモ slice_4.go
  50. 50. (3)スライスを拡張する copyとappend関数 書式は下記の通り func copy(dst, src []T) int 処理内容は、元のスライスから先のス ライスにデータをコピーする コピーした要素数を返す
  51. 51. (3)スライスを拡張する copyとappend関数 copy関数は異なるlengthのスライス でもコピーできる var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7} var s = make([]int, 6) n1 := copy(s, a[0:]) //n1=6, s=[]int{0,1,2,3,4,5} デモ slice_4.go
  52. 52. (3)スライスを拡張する copyとappend関数 スライスにデータを追加するには、 append関数を使用する
  53. 53. (3)スライスを拡張する copyとappend関数 書式は下記の通り func append(s []T, x ...T) []T 処理内容は、スライスsの最後に、 要素xを追加する より大きな容量が必要なら(自動的に)拡張 してくれる
  54. 54. (3)スライスを拡張する copyとappend関数 s3 := make([]int,1) // s3 == []int{0} // cap(s3) == 1 s3 = append(s3, 1, 2, 3) // s3 == []int{0, 1, 2, 3} // cap(s3) == 4 デモ slice_4.go
  55. 55. (3)スライスを拡張する copyとappend関数 スライスにスライスを追加するには、 ...を使用する a := []string{“John”,”Paul”} b := []string{"George", "Ringo", "Pete"} a = append(a, b...) //a == []string{"John", "Paul", "George", "Ringo", "Pete"} デモ slice_4.go
  56. 56. (4)スライスから削除する スライスからある要素を削除するには //例えば3を削除したい場合 s := []int{1, 2, 3, 4, 5} s=append(s[:2],s[3:]...) //s==[]int{1, 2, 4, 5} ※スライスに対しては、delete関数みたい なものは用意されていません。 デモ slice_5.go
  57. 57. (4)スライスから削除する これだと容量は削除されない。 s = [1 2 3 4 5] len(s)= 5 cap(s)= 5 アドレス:0x42120400 s = [1 2 4 5] len(s)= 4 cap(s)= 5 アドレス:0x42120400 デモ slice_5.go
  58. 58. (4)スライスから削除する ひとまず、削除関数を作っておきます。 func delete(i int, s []int) []int{ ! s = append(s[:i], s[i+1:]...) ! return s } これは先程のを関数にまとめただけ。 もちろん容量は削除されない。 デモ slice_5.go
  59. 59. (4)スライスから削除する 容量を削除するには、このdelete関数内で 再スライスした長さ分の スライスcを作り、 作ったスライスに再スライスしたsをコピーします。 func delete(i int, s []int) []int{ ! s = append(s[:i], s[i+1:]...) ! c := make([]int, len(s)) ! copy(c, s) ! return c } デモ slice_5.go
  60. 60. 最後に Let’s enjoy Go life with Slice ! ご清聴ありがとうございました

Editor's Notes

  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • fmt.Printf(&amp;#x201C;a&amp;#x306E;&amp;#x578B;&amp;#xFF1A;%T&amp;#xA5;n&amp;#x201D;, a) //a&amp;#x306E;&amp;#x578B;&amp;#xFF1A; int\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • a[0]=1\ni := a[0]\ni = 2\nfmt.Println(&quot;i=&quot;,i) // i=2\nfmt.Println(&quot;a[0]=&quot;,a[0]) // a[0]=1\n\n
  • a[0]=1\ni := a[0]\ni = 2\nfmt.Println(&quot;i=&quot;,i) // i=2\nfmt.Println(&quot;a[0]=&quot;,a[0]) // a[0]=1\n\n
  • a[0]=1\ni := a[0]\ni = 2\nfmt.Println(&quot;i=&quot;,i) // i=2\nfmt.Println(&quot;a[0]=&quot;,a[0]) // a[0]=1\n\n
  • a[0]=1\ni := a[0]\ni = 2\nfmt.Println(&quot;i=&quot;,i) // i=2\nfmt.Println(&quot;a[0]=&quot;,a[0]) // a[0]=1\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • a[0]=1\ni := a[0]\ni = 2\nfmt.Println(&quot;i=&quot;,i) // i=2\nfmt.Println(&quot;a[0]=&quot;,a[0]) // a[0]=1\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

×