go-redisでのRedisデータ型の扱い方

# はじめに

Redisにて提供される以下3つのデータ構造のSetとGetを[go-redis](https://godoc.org/github.com/go-redis/redis)で実装する際のサンプルコードを載せた記事です。

* String
* List
* Hash(map, dictionary)

# 環境

macos: 10.13.6 High Sierra
Redis server version: 4.0.11
go version: go1.11

# ソースコード

```go:main.go
package main

import (
	"fmt"

	"github.com/go-redis/redis"
)

func main() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})
	fmt.Println("Redis client:", client)

	fmt.Println("---------------------------------------------------")
	fmt.Println("Start StringGetSet")
	StringGetSet(client)
	fmt.Println("---------------------------------------------------")
	fmt.Println("Start ListGetSet")
	ListGetSet(client)
	fmt.Println("---------------------------------------------------")
	fmt.Println("Start HashGetSet")
	HashGetSet(client)
	fmt.Println("---------------------------------------------------")
}

func StringGetSet(client *redis.Client) {
	key := "StringGetSet_Key"
	// Set
	err := client.Set(key, "StringGetSet_Val", 0).Err()
	if err != nil {
		fmt.Println("redis.Client.Set Error:", err)
	}

	// Get
	val, err := client.Get(key).Result()
	if err != nil {
		fmt.Println("redis.Client.Get Error:", err)
	}
	fmt.Println(val)
}

func ListGetSet(client *redis.Client) {
	key := "ListGetSet_Key"
	// Set
	listVal := []string{"val1", "va2", "val3"}
	err := client.RPush(key, listVal).Err()
	if err != nil {
		fmt.Println("redis.Client.RPush Error:", err)
	}

	// Get
	// Get by lrange
	lrangeVal, err := client.LRange(key, 0, -1).Result()
	if err != nil {
		fmt.Println("redis.Client.LRange Error:", err)
	}
	fmt.Println(lrangeVal)
	// Get by lindex
	lindexVal, err := client.LIndex(key, 2).Result()
	if err != nil {
		fmt.Println("redis.Client.LIndex Error:", err)
	}
	fmt.Println(lindexVal)
}

func HashGetSet(client *redis.Client) {
	key := "HashGetSet_Key"
	// Set
	for field, val := range map[string]string{"field1": "val1", "field2": "val2"} {
		fmt.Println("Inserting", "field:", field, "val:", val)
		err := client.HSet(key, field, val).Err()
		if err != nil {
			fmt.Println("redis.Client.HSet Error:", err)
		}
	}

	// Get
	// HGet(key, field string) *StringCmd
	hgetVal, err := client.HGet(key, "field1").Result()
	if err != nil {
		fmt.Println("redis.Client.HGet Error:", err)
	}
	fmt.Println(hgetVal)

	// HGetAll
	hgetallVal, err := client.HGetAll(key).Result()
	if err != nil {
		fmt.Println("redis.Client.HGetAll Error:", err)
	}
	// fmt.Println("reflect.TypeOf(hgetallVal):", reflect.TypeOf(hgetallVal)) // map[string]string
	fmt.Println(hgetallVal)
}
```

# 実行結果

Dockerの[公式イメージ](https://hub.docker.com/_/redis/)を利用しRedisを起動

```
docker run -d -p 6379:6379 --name myredis redis
```

Goのコードを実行

```
go run main.go
```

実行結果

```
Redis client: Redis<localhost:6379 db:0>
---------------------------------------------------
Start StringGetSet
StringGetSet_Val
---------------------------------------------------
Start ListGetSet
[val1 va2 val3]
val3
---------------------------------------------------
Start HashGetSet
Inserting field: field1 val: val1
Inserting field: field2 val: val2
val1
map[field1:val1 field2:val2]
---------------------------------------------------
```

# 参考

* https://godoc.org/github.com/go-redis/redis
* http://blog.sojiro.me/blog/2014/07/27/rediss-data-type-and-usage/