Golangでyamlファイルを読み書きする。

　Golangでyamlを読み書きする方法をメモっていきます。go-yaml/yamlというライブラリを使用します（https://github.com/go-yaml/yaml）。
### go-yaml/yamlパッケージの取得
go getで取ってきましょう↓

``` bash:go-yaml/yamlを取得
go get go-yaml/yaml
```

最初はViperというライブラリを使ってみたのですが、これは機能が多すぎて逆に使いづらく（ディスってるわけじゃないのですが）、その内部で使われてる go-yaml/yaml 自体を使った方が簡単でした。

### 読み込むファイル

読み込むyamlファイルですが、こんな感じとします↓

``` yaml:test.yaml
- first: hello
  second: world
- first: hoo
  second: var
```

### yamlファイルの読み込み

#### []map[string]string にマッピング

``` go:[]map[string]stringにマッピングする
package main                                           
                                                       
import (                                               
    "fmt"                                              
    "github.com/go-yaml/yaml"                          
    "io/ioutil"                                        
)                                           
                                                       
func main() {             
    // test.yamlを []byte として読み込みます。                             
    buf, err := ioutil.ReadFile("./test.yaml")               
    if err != nil {                                    
        fmt.Println(err)                               
        return                                         
    } 
                   
    // []byte を []map[string]string に変換します。                                                                        
    data, err := ReadOnSliceMap(buf)                    
    if err != nil {                                
        fmt.Println(err)                           
        return                                     
    }                                              
    fmt.Println(data)                               
}                                                                                    

// yaml形式の[]byteを渡すと[]map[string]stringに変換してくれる関数です。
func ReadOnSliceMap(fileBuffer []byte) ([]map[string]string, error) {
    data := make([]map[string]string, 20)
    // ここで変換を行っています。
    // []byteを渡すとデータ型に合わせて上手い事マッピングしてくれます。                            
    err := yaml.Unmarshal(fileBuffer, &data)                         
    if err != nil {                                                  
        fmt.Println(err)                                             
        return nil, err                                              
    }                                                                
    return data, nil                                                 
}                                                                                                                          
```

#### []struct にマッピング

``` go:[]map[string]stringにマッピングする
package main                                           
                                                       
import (                                               
    "fmt"                                              
    "github.com/go-yaml/yaml"                          
    "io/ioutil"                                        
)

// マッピングする構造体です。
// どういうわけか、大文字じゃないとダメのようです。
type Test struct {  
    First  string   
    Second string   
}                                                          
                                                       
func main() {                                          
    buf, err := ioutil.ReadFile("./test.yaml")               
    if err != nil {                                    
        fmt.Println(err)                               
        return                                         
    }             
    
    // []byte を []Test に変換します。                                         
    data, err := ReadOnStruct(buf)                    
    if err != nil {                                
        fmt.Println(err)                           
        return                                     
    }                                              
    fmt.Println(data)                               
}       
                                               
// yaml形式の[]byteを渡すと[]Testに変換してくれる関数です。
func ReadOnStruct(fileBuffer []byte) ([]Test, error) {
    data := make([]Test, 20) 
    // []map[string]string のときと使う関数は同じです。
    // いい感じにマッピングしてくれます。                  
    err := yaml.Unmarshal(fileBuffer, &data)          
    if err != nil {                                   
        fmt.Println(err)                              
        return nil, err                               
    }                                                 
    return data, nil                                  
}                                                                                                             
```

### データをyaml形式でファイルに保存する
データを yaml.marshal で []byte に変換し、それをyamlファイルに書き込むといった感じになります。つまりこんな感じ↓

``` go:yaml形式のファイルに保存する
package main                                           
                                                       
import (                                               
    "fmt"                                              
    "github.com/go-yaml/yaml"                          
    "io/ioutil"                                        
)

// マッピングする構造体です。
type Test struct {  
    First  string   
    Second string   
}                                                          
                                                       
func main() {                                          
    buf, err := ioutil.ReadFile("./test.yaml")               
    if err != nil {                                    
        fmt.Println(err)                               
        return                                         
    }       
                                               
    data, err := ReadOnStruct(buf)                    
    if err != nil {                                
        fmt.Println(err)                           
        return                                     
    }     
    
    // hello を hi に書き換えて保存します。                                         
    data[0].First = "hi"             
    err = WriteOnFile(fileName, data)
    if err != nil {                  
        fmt.Println(err)             
        return                       
    }                                                        
}                                                      

// yaml形式の[]byteを渡すと[]Testに変換してくれる関数です。
func ReadOnStruct(fileBuffer []byte) ([]Test, error) {
    data := make([]Test, 20) 
    // []map[string]string のときと使う関数は同じです。
    // いい感じにマッピングしてくれます。                  
    err := yaml.Unmarshal(fileBuffer, &data)          
    if err != nil {                                   
        fmt.Println(err)                              
        return nil, err                               
    }                                                 
    return data, nil                                  
}

// ファイル名とデータをを渡すとyamlファイルに保存してくれる関数です。
func WriteOnFile(fileName string, data interface{}) error { 
    // ここでデータを []byte に変換しています。
    buf, err := yaml.Marshal(data)                          
    if err != nil {                                         
        return err                                          
    }                                      
    // []byte をファイルに上書きしています。                 
    err = ioutil.WriteFile(fileName, buf, os.ModeExclusive) 
    if err != nil {                                         
        return err                                          
    }                                                       
    return nil                                              
}                                                                                                                                                                                                                                 
```

保存するとこんな感じ↓

``` yaml:保存した奴
- first: hi
  second: world
- first: hoo
  second: var

```

以上です。