こちらはGetWild AdventCalenderの22日目の記事です。
はじめに
しかし、書かねばなりません。
そうだgoにはgoroutineがあった
そこで私は思い出しました。普段使っているgoにはgoroutineがあることを。
これを使えば私もいつでも気軽にWildを得る事ができるはずです。
早速実装します
今回はgoroutineを用いて標準出力に"G" "e" "t" "W" "i" "l" "d" の
7文字からランダムに1文字抽出し、"GetWild"になったタイミングに何かが起こる事にします。
package main
import (
"fmt"
"math/rand"
"time"
)
var (
getWildWords = []string{"G", "e", "t", "W", "i", "l", "d"}
)
func main() {
c := make(chan string)
w := ""
for {
go getWildAndTough(c)
w += <-c
if len(w) == len(getWildWords) {
fmt.Println(w)
w = ""
}
}
}
func getWildAndTough(c chan string) {
rand.Seed(time.Now().UnixNano())
c <- getWildWords[rand.Intn(len(getWildWords))]
}
これでgoroutineを使用して、チャンネル経由で7文字の文字列を受け取る事が出来るようになりました。
しかし、これは if len(r) == len(getWildWords) {
あたりがかっこ悪いので7本のワーカーでそれぞれ1文字づつ返却するようにします。
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var (
getWildWords = []string{"G", "e", "t", "W", "i", "l", "d"}
)
func main() {
wg := &sync.WaitGroup{}
c := make(chan string)
for {
r := ""
for i := 0; i < 7; i++ {
wg.Add(1)
go getWildAndTough(wg, c)
r += <-c
}
wg.Wait()
fmt.Println(r)
r = ""
}
close(c)
}
func getWildAndTough(wg *sync.WaitGroup, c chan string) {
defer wg.Done()
rand.Seed(time.Now().UnixNano())
c <- getWildWords[rand.Intn(len(getWildWords))]
}
syncパッケージを利用し、それぞれのgoroutineが処理を終えるまで待ち文字を出力するようにしました。駅の掲示板にXYZと書いて待っている時の心で書きます。
package main
import (
"fmt"
"math/rand"
"os/exec"
"sync"
"time"
)
var (
getWildWords = []string{"G", "e", "t", "W", "i", "l", "d"}
g string
)
const (
textGetWild = `
____ _ __ ___ _ _
/ ___| ___| |_ \ \ / (_) | __| |
| | _ / _ \ __| \ \ /\ / /| | |/ _ |
| |_| | __/ |_ \ V V / | | | (_| |
\____|\___|\__| \_/\_/ |_|_|\__,_|
`
)
func init() {
for _, v := range getWildWords {
g += v
}
}
func main() {
wg := &sync.WaitGroup{}
c := make(chan string)
for {
w := ""
for i := 0; i < 7; i++ {
wg.Add(1)
go getWildAndTough(wg, c)
w += <-c
}
wg.Wait()
if isGetWild(w) {
fmt.Println(textGetWild)
exec.Command("say", "-v", "Ava", w).Run()
break
}
w = ""
}
close(c)
}
func getWildAndTough(wg *sync.WaitGroup, c chan string) {
defer wg.Done()
rand.Seed(time.Now().UnixNano())
c <- getWildWords[rand.Intn(len(getWildWords))]
}
func isGetWild(w string) bool {
if g == w {
return true
}
return false
}
上記のようにすれば下記のようにGetWildとAAを出力させつつ
槇村香のように「Get Wild」と喋ります。
____ _ __ ___ _ _
/ ___| ___| |_ \ \ / (_) | __| |
| | _ / _ \ __| \ \ /\ / /| | |/ _ |
| |_| | __/ |_ \ V V / | | | (_| |
\____|\___|\__| \_/\_/ |_|_|\__,_|
皆様、2016年も残り短くなりましたが2017年もタイヤを切りつける勢いで
GetWildしていきましょう。くれぐれもWildなコードは書きませんように。