第2回発表メモ, 第3回発表メモ のように 細かく箇条書きにするのも面倒になってきたので、 各章の概要だけ、、、、
map を基底とした Dictionary
型 を定義
type Dictionary map[string]string
自分で定義した custom type の Dictionary
型 に対して、 CRUD
(Create, Read, Update, Delete) API を以下の順で実装していく
Search
メソッド (Read)- 指定した key が map に存在しない場合 は
ErrNotFound
を返す- map の振る舞いをそのまま利用すると ゼロ値が返る ※後述 (
v := map["new_key"]
)
- map の振る舞いをそのまま利用すると ゼロ値が返る ※後述 (
- 指定した key が map に存在しない場合 は
Add
メソッド (Create)- 既に同じ key が map に登録されていた場合 は
ErrWordExists
を返す- map の振る舞いをそのまま利用すると Update になってしまう (
map["exists_key"] = "val"
)
- map の振る舞いをそのまま利用すると Update になってしまう (
- 既に同じ key が map に登録されていた場合 は
Update
メソッド- 指定した key が map に存在しない場合 は
ErrWordDoesNotExist
を返す- map の振る舞いをそのまま利用すると Create になってしまう (
map["new_key"] = "val"
)
- map の振る舞いをそのまま利用すると Create になってしまう (
- 指定した key が map に存在しない場合 は
Delete
メソッド- 組み込みの
delete
関数 をそのまま利用.- 指定した key で map に存在しない場合は 無視される
- 戻り値無し
- 組み込みの
- comparable type のみ
- slice, map, function は not comparable なので key に指定できない
map
is a reference type (map
は 参照型) ->nil
になる可能性有り
空のマップ変数を初期化しては❌
var m map[string]string
map の作成方法
var dictionary = map[string]string{}
// OR
var dictionary = make(map[string]string)
- 補足: A Tour of Go: Maps 参照
> マップのゼロ値は nil です
> nil マップはキーを持っておらず、またキーを追加することもできません
> make 関数は指定された型の、初期化され使用できるようにしたマップを返します
- 補足: 50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs の
Using "nil" Slices and Maps
参照> It's OK to add items to a "nil" slice, but doing the same with a map will produce a runtime panic.
("nil" slice にアイテムを追加してもかまいませんが、 map で同じ操作を行うと runtime panic が発生します)
definition, ok := d[word]
if !ok {
return "", ErrNotFound
}
- key が存在しない場合
- 1個目の戻り値 = ゼロ値(string の場合は
""
) - 2個目の戻り値 =
false
- 1個目の戻り値 = ゼロ値(string の場合は
- error を variable として定義
var ErrNotFound = errors.New("could not find the word you were looking for")
↓ リファクタリング
- error を
const
に変更string
を 基底 とした Custom Type を定義Error() string
メソッド を実装 ->error
interface を満たすstring
なので const 化できる
const (
ErrNotFound = DictionaryErr("could not find the word you were looking for")
ErrWordExists = DictionaryErr("cannot add word because it already exists")
ErrWordDoesNotExist = DictionaryErr("cannot update word because it does not exist")
)
type DictionaryErr string
func (e DictionaryErr) Error() string {
return string(e)
}
- 補足: A Tour of Go: Constants 参照
> 定数は、文字(character)、文字列(string)、boolean、数値(numeric)のみで使えます
Greet
関数 の test を行うfmt.Fprintf
を利用して writer に string を書き込む 関数
func Greet(writer io.Writer, name string) {
fmt.Fprintf(writer, "Hello, %s", name)
}
- 第1引数 の
io.Writer
に対して DI する- test では ->
*bytes.Buffer
main
関数 からは ->os.Stdout
- HTTP server では ->
http.ResponseWriter
- test では ->
type Writer interface {
Write(p []byte) (n int, err error)
}
- 全て
Write([]byte) (int, error)
メソッド を持つ ->io.Writer
を満たす*bytes.Buffer
,os.Stdout
(実体は*os.File
)http.ResponseWriter
は interface ( 実体は*http.response
(*conn
のreadRequest
メソッド でセットされてる) )
fmt.Printf
は 中でfmt.Fprintf
を呼び出しfmt.Fprintf
の 第1引数 にos.Stdout
(実体は*os.File
) を渡している
func Printf(format string, a ...interface{}) (n int, err error) {
return Fprintf(os.Stdout, format, a...)
}
fmt.Fprintf
の 第1引数 はio.Writer
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
// 中略
}
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
HandlerFunc
型 は 関数 「func(ResponseWriter, *Request)
」 型 を 基底 とする 型- -> 関数 「
func(ResponseWriter, *Request)
」 はHandlerFunc
型 に 変換可能
- -> 関数 「
HandlerFunc
型 はServeHTTP
メソッド を持つServeHTTP
メソッド は 関数自身(=f
) を呼び出す
- 後の章
12. Select
,15. Context
でまた出ます
func ListenAndServe(addr string, handler Handler) error {
// 中略
}
- 第2引数 は
Handler
interface
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
HandlerFunc
型 はServeHTTP
メソッド を持つ- ->
Handler
interface を満たす - ->
Handler
型 の変数に 代入可能- ->
ListenAndServe
の 第2引数 に 渡せる
- ->
- ->
func MyGreeterHandler(w http.ResponseWriter, r *http.Request) {
Greet(w, "world")
}
func main() {
err := http.ListenAndServe(":5000", http.HandlerFunc(MyGreeterHandler))
if err != nil {
fmt.Println(err)
}
}
※今回はここまで
次回 -> 第5回(2020/01/22) 実施です (第5回(2020/01/22) 発表メモ)