O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
Go言語のスライスを  理解しよう 2012/08/25 GDG Kobe
自己紹介• 河本 泰孝 @yasi_life → @kwmt27• 私とGo言語との関わり  • 2011年のDevQuizで初めて触った  • 2012年1月のGo言語勉強会に参加  • 2012年4月の東海GTUGさんのGAE  勉強会でG...
自己紹介• 最近では公式サイトの  • Writing Web Applications  • Go Slices を翻訳してみたり。 https://github.com/ kwmt/golangwiki/wiki
自己紹介ということで、• 1月のGo言語勉強会では スライスまで出来なくて、• 自分でスライスについて翻訳してみた ので公式サイトのGo Slicesを元に発表させて頂きます。
もくじ
もくじ1.かるく復習2.Go言語の配列とは?3.スライスとは?(1)特徴(2)内部構造(3)拡張する(4)削除する
進め方説明しながら、実際に動きを確かめるデモをしていきたいと思います。もし可能なら下記のサイトで動かせるので一緒に動かして行きましょう。http://play.golang.org/でもそこまでガッツリやって頂く時間がないかもしれません。半ハン...
1.かるく復習変数宣言のいろいろ var a int = 1 // int型 a := 1標準出力するには import “fmt” fmt.Printf(“a=%d¥n”, a)      デモ slice_0.go
2.Go言語の配列とは?
配列の定義方法長さ(length) と要素の型を指定var a [4]int
配列の定義方法長さ(length) と要素の型を指定var a [4]int   長さ (length)
配列の定義方法長さ(length) と要素の型を指定var a [4]int   長さ          要素の型 (length)
配列の特徴  a[n]はn番目の要素にアクセス可能//配列宣言var a [4]int//0番目の要素に1を代入a[0] = 1//変数iを宣言してa[0]をiに代入i := a[0]// 表示すると// i = 1          デモ s...
配列の特徴 明示的な初期化は不要 (自動的に0で初期化されています)前ページの例の0番目の要素以外は値0となっています。// a[0]==1,a[1]==0,a[2]==0,a[3]==0          デモ slice_1.go
配列の特徴配列変数は配列全体を表しています。つまりC言語のように、先頭の配列要素へのポインタではありません。イメージ
配列の特徴 配列リテラルの書き方・要素数を指定するb := [2]string{“Penn”,”Teller”}・要素数を指定しない (コンパイラに数えさせる)b := [...]string{“Penn”,”Teller”}         ...
3.スライスとは?
スライスの定義方法長さ(length) と要素の型を指定var a []int   長さ (length)     要素の型
スライスの定義方法長さ(length) と要素の型を指定var a []int   長さ (length)     要素の型
(1)スライスの特徴 スライスリテラルの書き方letters := []string{“a”,”b”,”c”,”d”}要素数の指定以外は、配列リテラルの書き方と同じ
(1)スライスの特徴組み込み関数 makeを使ってスライスを作成できる。
(1)スライスの特徴         make関数とはmake関数の書式func make([]T, len, cap) []TT:要素の型len:長さ(length)cap:容量(capacity)(オプション)
(1)スライスの特徴          make関数とはmake関数は、スライス型のオブジェクトを確保し、初期化する。1番目の引数の型と同じ型を返す。ポインタを返すわけではない。 func make([]T, len, cap) []T
(1)スライスの特徴make関数を使ってスライスを作成する例var s []bytes = make([]byte, 5, 5)// s=[0 0 0 0 0]// sの型=[]uint8       デモ slice_2.go
(1)スライスの特徴容量(capacity)は省略できるvar s []bytes = make([]byte, 5, 5)      次のように簡略化できるs := make([]byte, 5)※容量を省略すると、長さ=容量となる     ...
(1)スライスの特徴スライスの長さ(length)と容量(capacity)を調べるには、組み込み関数のlenとcapを使用する。len(s) // == 5cap(s) // == 5        デモ slice_2.go
(1)スライスの特徴     スライスのゼロ初期化さてないスライスの値:nilスライス==nilならば、  len,cap関数は0を返す     デモ slice_2.go
(1)スライスの特徴               re-slice 再スライス化可能b := []byte{‘g’,’o’,’l’,’a’,‘n’,’g’}c := b[1:4]// c=[]byte{’o’,’l’,’a’}// スライスcは...
(1)スライスの特徴     re-slice b[1:4] デモ slice_2.go
(1)スライスの特徴     re-slice b[1:4] デモ slice_2.go
(1)スライスの特徴     re-slice b[1:4]これら2つの数字は  省略可能 デモ slice_2.go
(1)スライスの特徴            re-sliceb[:]b[:2]b[2:]        デモ slice_2.go
(1)スライスの特徴              re-sliceb[:]    ==bb[:2]b[2:]        デモ slice_2.go
(1)スライスの特徴              re-sliceb[:]    ==bb[:2]   ==[]byte{‘g’,’o’}b[2:]        デモ slice_2.go
(1)スライスの特徴              re-sliceb[:]    ==bb[:2]   ==[]byte{‘g’,’o’}b[2:]   ==[]byte{‘l’,’a’,’n’,’g’}        デモ slice_2.go
(1)スライスの特徴         re-slice自分のコードで、s[:len(s)]と再スライスしてたよ、、、へへ。     デモ slice_2.go
(1)スライスの特徴        re-slice配列からスライスを作る    デモ slice_2.go
(1)スライスの特徴                  re-slice  配列からスライスを作るx := [3]string{"Лайка", "Белка", "Стрелка"}s := x[:] // スライスsはxの記憶領域を参照  ...
(2)スライスの内部構造スライスは、配列内の連続した領域への    イメージ参照であり、以下の3つから構成される。๏配列へのポインタ๏セグメントの長さ(length)๏容量(capacity) (セグメントの最大の長さ)
(2)スライスの内部構造s := make([]byte,5)イメージ       デモ slice_3.go
(2)スライスの内部構造s = s[2:4]イメージ       デモ slice_3.go
(2)スライスの内部構造再スライスされた要素を変更すると、元のスライスの要素も変更される。d :=   []byte{r, o, a, d}e :=   d[2:]// e   == []byte{a, d}e[1]   == m// e   ...
(2)スライスの内部構造len < cap の場合、lenをcapまで拡張できるs = s[:cap(s)]イメージ       デモ slice_3.go
(2)スライスの内部構造容量を超えて拡張できない。
(2)スライスの内部構造容量を超えて拡張できない。容量を増やせば、拡張できる。
(3)スライスを拡張する      copyとappend関数容量(capacity)を増やすには、1.新しく大きな容量のスライスを作成2.その新しいスライスに元のスライスの内容をコピーする
(3)スライスを拡張する         copyとappend関数s := make([]byte, 5)t := make([]byte, len(s),                (cap(s)+1)*2)for i := range...
(3)スライスを拡張する         copyとappend関数s := make([]byte, 5)t := make([]byte, len(s),                (cap(s)+1)*2)for i := range...
(3)スライスを拡張する        copyとappend関数 copy関数を使って次のように書けるs := make([]byte, 5)t := make([]byte, len(s),               (cap(s)+1)...
(3)スライスを拡張する        copyとappend関数 書式は下記の通りfunc copy(dst, src []T) int 処理内容は、元のスライスから先のス ライスにデータをコピーする コピーした要素数を返す
(3)スライスを拡張する       copyとappend関数copy関数は異なるlengthのスライスでもコピーできるvar a = [...]int{0, 1, 2, 3,                  4, 5, 6, 7}var ...
(3)スライスを拡張する     copyとappend関数スライスにデータを追加するには、append関数を使用する
(3)スライスを拡張する       copyとappend関数書式は下記の通りfunc append(s []T, x ...T) []T処理内容は、スライスsの最後に、要素xを追加するより大きな容量が必要なら(自動的に)拡張してくれる
(3)スライスを拡張する         copyとappend関数s3   := make([]int,1)//   s3 == []int{0}//   cap(s3) == 1s3   = append(s3, 1, 2, 3)//   ...
(3)スライスを拡張する        copyとappend関数 スライスにスライスを追加するには、 ...を使用するa := []string{“John”,”Paul”}b := []string{"George",           ...
(4)スライスから削除するスライスからある要素を削除するには//例えば3を削除したい場合s := []int{1, 2, 3, 4, 5}s=append(s[:2],s[3:]...)//s==[]int{1, 2, 4, 5}※スライスに対...
(4)スライスから削除するこれだと容量は削除されない。s = [1 2 3 4 5]len(s)= 5 cap(s)=   5アドレス:0x42120400s = [1 2 4 5]len(s)= 4 cap(s)=   5アドレス:0x421...
(4)スライスから削除する  ひとまず、削除関数を作っておきます。func delete(i int, s []int) []int{! s = append(s[:i], s[i+1:]...)! return s}  これは先程のを関数にま...
(4)スライスから削除する  容量を削除するには、このdelete関数内で  再スライスした長さ分の スライスcを作り、  作ったスライスに再スライスしたsをコピーします。func delete(i int, s []int) []int{! ...
最後にLet’s enjoy Go life with Slice !ご清聴ありがとうございました
Próximos SlideShares
Carregando em…5
×

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

120825にGDGKOBEで発表した資料です。

  • Seja o primeiro a comentar

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) []TT:要素の型len:長さ(length)cap:容量(capacity)(オプション)
  23. 23. (1)スライスの特徴 make関数とはmake関数は、スライス型のオブジェクトを確保し、初期化する。1番目の引数の型と同じ型を返す。ポインタを返すわけではない。 func make([]T, len, cap) []T
  24. 24. (1)スライスの特徴make関数を使ってスライスを作成する例var s []bytes = make([]byte, 5, 5)// s=[0 0 0 0 0]// sの型=[]uint8 デモ slice_2.go
  25. 25. (1)スライスの特徴容量(capacity)は省略できるvar s []bytes = make([]byte, 5, 5) 次のように簡略化できるs := make([]byte, 5)※容量を省略すると、長さ=容量となる デモ slice_2.go
  26. 26. (1)スライスの特徴スライスの長さ(length)と容量(capacity)を調べるには、組み込み関数のlenとcapを使用する。len(s) // == 5cap(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-sliceb[:]b[:2]b[2:] デモ slice_2.go
  33. 33. (1)スライスの特徴 re-sliceb[:] ==bb[:2]b[2:] デモ slice_2.go
  34. 34. (1)スライスの特徴 re-sliceb[:] ==bb[:2] ==[]byte{‘g’,’o’}b[2:] デモ slice_2.go
  35. 35. (1)スライスの特徴 re-sliceb[:] ==bb[: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) == 1s3 = 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アドレス:0x42120400s = [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 !ご清聴ありがとうございました

×