github.com/samber/lo をつかったコレクション操作
package _go
import (
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"testing"
)
func TestLodash(t *testing.T) {
type ArtistID int
type Artist struct {
ID ArtistID
Name string
Age int
}
type ArtistMap = map[ArtistID]Artist
artists := []Artist{
{
ID: 1,
Name: "A",
Age: 25,
},
{
ID: 2,
Name: "B",
Age: 45,
},
{
ID: 3,
Name: "C",
Age: 30,
},
}
var filter1 []Artist = lo.Filter(artists, func(a Artist, i int) bool {
return a.Age > 29
})
assert.Equal(t, 2, len(filter1))
var artistMap ArtistMap = lo.KeyBy[ArtistID, Artist](artists, func(a Artist) ArtistID {
return a.ID
})
assert.Equal(t, `C`, artistMap[3].Name)
}
- メソッドchainができない?(戻り値がRaw Slice)
- funcで受ける時のIDE支援がいまのところきかない (LSPあればOKということにならない?)
github.com/neurocollective/go_chainable をつかったコレクション操作
package _go
import (
"github.com/neurocollective/go_chainable/lists"
"github.com/stretchr/testify/assert"
"testing"
)
func TestChainable(t *testing.T) {
type ArtistID int
type Artist struct {
ID ArtistID
Name string
Age int
}
artists := []Artist{
{
ID: 1,
Name: "A",
Age: 25,
},
{
ID: 2,
Name: "B",
Age: 45,
},
{
ID: 3,
Name: "C",
Age: 30,
},
}
list := lists.New[Artist, any](artists)
filter1 := list.
Filter(func(a Artist, i int) bool {
return a.Age >= 25
}).
Filter(func(a Artist, i int) bool {
return a.ID == 2
})
_, size := filter1.Size()
assert.Equal(t, 1, size)
_, first := filter1.First()
assert.Equal(t, `B`, first.Age)
}
- GroupBy的なものでmapに変換できない? (見落としてるかも)
ジェネリクス/自前で思い付くユースケース
簡単な可変型のin/outを持つタスクルーターを書く時、interface{}
がたくさん出てくるのを防げないか
package _go
type UserHandler interface {
Handle(in UserInput) (out UserOutput, err error)
}
type UserInput struct {
UserID int `json:"user_id"`
}
type UserOutput struct {
UserID int `json:"user_id"`
}
type implUserHandler struct {
}
func (self implUserHandler) Handle(in UserInput) (out *UserOutput, err error) {
fmt.Println("call")
return &UserOutput{
UserID: in.UserID,
}, nil
}
package _go
import (
"encoding/json"
fmt "fmt"
"github.com/stretchr/testify/assert"
"testing"
)
func TestHandler(t *testing.T) {
userHandler := implUserHandler{}
taskRouter := map[string]HandlerFunc{
`/user/handle`: func(rawInput []byte) (any, error) {
return userHandler.Handle(toHandlerInput(rawInput, UserInput{}))
},
}
resp, _ := taskRouter[`/user/handle`]([]byte(`{ "user_id" : 1 }`))
respAsjson, _ := json.Marshal(resp)
assert.JSONEq(t, `{"user_id":1}`, string(respAsjson))
}
type HandlerFunc = func(in []byte) (interface{}, error)
func toHandlerInput[T any](raw []byte, in T) T {
_ = json.Unmarshal(raw, &in)
return in
}
jsonをUnmarshalして返す toHandlerInput
だけ使ったけど、筋としてはほとんどジェネリクス関係ないというか、どっちかというとリフレクションの領域のような気もしてきた