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