Golangメモ

Goのスライスについて、https://go-tour-jp.appspot.com/moretypes/11より
スライスは長さ( length )と容量( capacity )の両方を持っています。
スライスの長さは、それに含まれる要素の数です。
スライスの容量は、スライスの最初の要素から数えて、元となる配列の要素数です。
スライスは、開始地点の指定が0より大きい数字だと、その分縮む。
下記では、s = s[2:]としたときに、配列先頭の2つの値が削除され、sは3番目の値から[5,7(,11,13)]になる(その前のs = s[:4]は引き継がれ、s[2:4]として3番目~4番目の値をもつ)。また、「配列から削除」の言葉通り、cap(s)が2小さくなる。
sに改めてアクセスする際、元の3番目の値から、添字は0になる。s = s[1:]とすると、配列先頭の1つの値が削除され、[7,11,13]となる。
添字がリセット(?)されることを意識しないと、s[:5]などとして、エラーを吐くことになる。注意。
panic: runtime error: slice bounds out of range [:5] with capacity 4
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// Slice the slice to give it zero length.
s = s[:0]
printSlice(s)
// Extend its length.
s = s[:4]
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
s = s[:3]
printSlice(s)
s = s[1:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]
len=3 cap=4 [5 7 11]
len=2 cap=3 [7 11]

インデックスや値は、 " _ "(アンダーバー) へ代入することで捨てることができます。
Pythonのfor _ in range(10):
の_
って捨ててたのか…
(ちゃんとメモリは使っているらしいが)

動いた。嬉しい。備忘録。
x^yめっちゃきれい!
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
lx := make([]int, dx)
ly := make([]int, dy)
var picture [][]uint8
for i := range ly {
var tmp []uint8
for j := range lx {
tmp = append(tmp, uint8((i + j) / 2))
}
picture = append(picture, tmp)
}
return picture
}
func main() {
pic.Show(Pic)
}

Goのmap直感的で、慣れたら超書きやすそう。
Exercise: Mapsより、package main
import (
"golang.org/x/tour/wc"
"strings"
)
func WordCount(s string) map[string]int {
var mp map[string]int
mp = make(map[string]int)
for _, w := range strings.Fields(s) {
if _, ok := mp[w]; ok {
mp[w]++
} else {
mp[w] = 1
}
}
return mp
}
func main() {
wc.Test(WordCount)
}

わりと大事なこと
ポインタレシーバを使う2つの理由があります。
ひとつは、メソッドがレシーバが指す先の変数を変更するためです。
ふたつに、メソッドの呼び出し毎に変数のコピーを避けるためです。 例えば、レシーバが大きな構造体である場合に効率的です。

例えば、
// ダメ
// len=4 cap=6
s = s[:4]
print(s[5])
// イケル
// len=6 cap=6
s = s[:6]
print(s[5])
という感じ。
capはスライスし直すときに初めて意味を持つと解釈。
他の言語同様、index範囲などはあくまでlenで考える。
package main
import "golang.org/x/tour/reader"
type MyReader struct{}
// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (r MyReader) Read(b []byte) (int, error) {
for i := 0; i < len(b); i++ {
b[i] = 'A'
}
return len(b), nil
}
func main() {
reader.Validate(MyReader{})
}

channelsは先入れ先出しとのこと。
処理が終わった順にキューに追加されるため、必ずしもコードの上から順番に値が入るわけではない。A Tour of GoのChannelsでは、結果だけ見ると後入れ先出しになっていたので、上記調べた。

interfaceメモ
- インタフェースの実体は構造体のポインタ
func New() Interface {
return &struct
}

middlewareは要するに引数http.Handlerをとってhttp.Handlerを返す関数

chi
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.URLFormat)
r.Use(render.SetContentType(render.ContentTypeJSON))
chatgpt
chiはGoで書かれた軽量なHTTPルーターで、多くの便利なミドルウェアや機能を提供しています。指定されたミドルウェアについて説明します。
middleware.RequestID: このミドルウェアは、各HTTPリクエストに一意なIDを自動的に割り当てます。便宜上のトレーシングに役立ちます。
middleware.Logger: リクエストに関する基本的なログ情報をコンソールに出力します。デバッグや監視に有用です。
middleware.Recoverer: パニックが発生した場合に捕捉して適切に処理します。これによりアプリケーションがクラッシュするのを防ぎます。
middleware.URLFormat: リクエストURLを正規化し、末尾のスラッシュや複数のスラッシュを適切に処理します。
render.SetContentType(render.ContentTypeJSON): このミドルウェアは、レスポンスのContent-Typeヘッダーをapplication/jsonに設定します。
これらのミドルウェアはchiが提供するもので、APIやWebサーバーの実装を簡単かつ効率的に行えるように設計されています。