昨年の記憶からすると、golangのスライスと配列は宣言が似ているものの、同じように使おうとすると怒られる、という代物だった。
あまり考えず、思いつくままに書いてみよう。
01: package main 02: 03: 04: func gogo(bababa int[]) { 05: for i := 0; i < bababa.length; i++ { 06: bababa[i] = i 07: } 08: } 09: 10: func main() { 11: var momomo int[]; 12: 13: momomo = new int[10]; 14: gogo(momomo) 15: for i := 0; i < momomo.length; i++ { 16: fmt.Printf("[%d] = %d\n", i, momomo[i]) 17: } 18: }
はい、コンパイルエラーです。
golangは型を後に書くタイプだったよなー、とか、Javaの配列は型名の後だったよなー、とか、そんなことを考えてやってみたのだが、やっぱりダメだった。
01: package main 02: 03: import "fmt" 04: 05: func gogo(bababa []int) { 06: for i := 0; i < len(bababa); i++ { 07: bababa[i] = i 08: } 09: } 10: 11: func main() { 12: var momomo []int 13: 14: momomo = make([]int, 5) 15: gogo(momomo) 16: for i := 0; i < len(momomo); i++ { 17: fmt.Printf("[%d] = %d\n", i, momomo[i]) 18: } 19: }
型名の前にスライスであることを表すのだな。
そして、スライスの要素数はlen()。確保済みの要素数はcap()らしい。
for文で要素数の数だけループさせるというのは、最近の言語ではあまりやらん気がする。
でもforeachっぽい書き方をすると代入ができないんじゃなかろうか?
01: package main 02: 03: import "fmt" 04: 05: func gogo(bababa []int) { 06: for i, value := range(bababa) { 07: value = i 08: } 09: } 10: 11: func main() { 12: var momomo []int 13: 14: momomo = make([]int, 5) 15: gogo(momomo) 16: for i, val := range(momomo) { 17: fmt.Printf("[%d] = %d\n", i, val) 18: } 19: }
これはコンパイルエラーになった。
gogo()の方でvalueを使っていないという扱いになったからだ。
01: package main 02: 03: import "fmt" 04: 05: func gogo(bababa []int) { 06: for i := range bababa { 07: bababa[i] = i 08: } 09: } 10: 11: func main() { 12: var momomo []int 13: 14: momomo = make([]int, 5) 15: gogo(momomo) 16: for i, val := range momomo { 17: fmt.Printf("[%d] = %d\n", i, val) 18: } 19: }
これなら通った。
第2戻り値を使わないので、最初は
for i, _ := range bababa {
にしたのだが、これはコンパイルエラーではないものの、警告されてしまった。
省略するものらしい。
range(momomo)は、vscodeのフォーマッタを使ったら括弧を外されてしまった。
しかし、len(momomo)はダメらしい。
lenは関数で、rangeは関数ではないということだろうか?
rangeはRnageClauseというものらしい。れんじくらうぜ?
なんでもかんでもrangeが使えるわけではない。array, slice, string, map, channel。
戻り値も、1stと2ndでちゃんと決められているそうだ。
rangeはfor文専用のようだ。
だからlenとは扱いが違うのだろう。
これで終わろうと思ったが、よくわからないサンプルがあった。
01: package main 02: 03: import "fmt" 04: 05: func gogo(bababa []int) { 06: for i := range bababa { 07: bababa[i] = 10 + i 08: } 09: } 10: 11: func lolo(bababa []int) { 12: i := 3 13: for i, bababa[i] = range bababa { 14: 15: } 16: } 17: 18: func main() { 19: var momomo []int 20: 21: momomo = make([]int, 5) 22: gogo(momomo) 23: lolo(momomo) 24: for i, val := range momomo { 25: fmt.Printf("[%d] = %d\n", i, val) 26: } 27: }
ちなみに、オリジナルはこうだ。
i = 2 x = []int{3, 5, 7} for i, x[i] = range x { // set i, x[2] = 0, x[0] break } // after this loop, i == 0 and x == []int{3, 5, 3}
breakがあってもなくても、なんか動作がよくわからない。
今日は眠たいので、また次回だ。
あ、配列のこと書き忘れた!
まあ、それも含めた次回だな。。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。