Open10

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]
れあれあ

https://go-tour-jp.appspot.com/moretypes/18
Exercise: Slices より、
動いた。嬉しい。備忘録。
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直感的で、慣れたら超書きやすそう。
https://go-tour-jp.appspot.com/moretypes/23
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)
}
れあれあ

わりと大事なこと

https://go-tour-jp.appspot.com/methods/8

ポインタレシーバを使う2つの理由があります。

ひとつは、メソッドがレシーバが指す先の変数を変更するためです。

ふたつに、メソッドの呼び出し毎に変数のコピーを避けるためです。 例えば、レシーバが大きな構造体である場合に効率的です。

れあれあ

https://go-tour-jp.appspot.com/methods/22より
for i := 0; i < cap(b); i++とすると、panicを起こした。スライスの状態で、cap的に行けてもlen的にダメなら無理!ってことみたい。
例えば、

// ダメ
// 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{})
}
れあれあ

interfaceメモ

  • インタフェースの実体は構造体のポインタ
func New() Interface {
    return &struct
}
れあれあ

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サーバーの実装を簡単かつ効率的に行えるように設計されています。