LoginSignup
4
0

More than 1 year has passed since last update.

Go1.18がでたのでコレクション操作とかいくつか触った記録

Last updated at Posted at 2022-03-16

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 だけ使ったけど、筋としてはほとんどジェネリクス関係ないというか、どっちかというとリフレクションの領域のような気もしてきた

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0