昨天已經成功把檔案載入變成 []byte
型態,今天要來讀 YAML 檔了。
分析
昨天有提到會使用 go-yaml
解析 YAML 資料,資料格式參考 Faker,大概會長像下面這樣:
lastNames: - 李 - 王 - 張 - 劉 - 陳 - 楊 - 趙 - 黃 - ...
characterMale: - 家 - 豪 - 志 - 明 - ...
characterFemale: - 雅 - 婷 - 春 - 嬌 - ...
|
go-yaml
的用法大概如下:
s := NamesProvider{} yaml.Unmarshal(bytes, s)
fmt.Println(s)
|
這樣應該就可以開始實作了。
開工
開始前,一樣要先重構:把切目錄和讀檔的任務放到最外層(main.go
)。
不過因為不大清楚 CLI 套件怎麼做全域的任務,所以不如就把解析 YAML 的任務先放在 resource
裡:
type NamesResource struct { LastNames []string `yaml:"lastNames"` CharacterMale []string `yaml:"characterMale"` CharacterFemale []string `yaml:"characterFemale"` }
func ParseFile(file string) (res NamesResource, err error) { r, err := ioutil.ReadFile(file) if err != nil { return res, err }
if err := yaml.Unmarshal(r, &res); err != nil { return res, err }
return res, nil }
|
其中需注意的是,go-yaml 預設會先把 field 轉全小寫,再去 YAML 的資料裡面找。而 LastNames field 預設會找 lastnames
的欄位,然後就找不到,這時會需要用 yaml:"lastNames"
指定要找的欄位。
其他兩個 Command 開頭先執行吧!之後有空再來想想該怎麼重構:
t, _ := provider.ParseFile(c.GlobalString("provider"))
fmt.Println(t)
|
今天這樣太簡單了。資料都有了,不如就把亂數取名實作出來吧!
回憶一下之前取名的方法(順便騙版面):
func (generator *Generator) Name() string { length := len(names)
return names[generator.rand.Intn(length)] }
|
這裡是用 generator.rand
取得亂數,再去口袋名單裡面取。但現在口袋名單變成了 NameResource
,最簡單的做法就是在 Generator 加一個 Resource field:
type Generator struct { rand *rand.Rand Resource NamesResource }
|
然後直接在 Command Action 指定:
res, _ := provider.ParseFile(c.GlobalString("provider"))
generator := provider.Create() generator.Resource = res
|
這樣裡面就會有資料可以用了。接著參考 Faker 的做法,它會把姓跟名分開,實作如下:
func (generator *Generator) Name() string { return generator.LastName() + generator.FirstName() }
func (generator *Generator) LastName() string { length := len(generator.Resource.LastNames) randomIndex := generator.rand.Intn(length)
return generator.Resource.LastNames[randomIndex] }
func (generator *Generator) FirstName() string { merge := append(generator.Resource.CharacterMale, generator.Resource.CharacterFemale...) length := len(merge) randomIndex := generator.rand.Intn(length)
return merge[randomIndex] }
|
展示
執行結果如下:
$ go run main.go generate Generate 10 楊雅 李婷 黃明 劉雅 陳明 楊豪 黃春 劉家 王嬌 趙家
|
詳細程式可以參考 PR Day 20
參考資料