20210615のGoに関する記事は5件です。

Golangサンプルコード: 構造体の情報を再帰的に読む

構造体を再帰的に読んでいく。 無限ループに陥らないようにチェックを入れた。 package main import "fmt" type Node struct { ID int Child *Node } func (n *Node) PrintID() { check := map[int]bool{} var printID func(n *Node) printID = func(n *Node) { fmt.Printf("%d\n", n.ID) check[n.ID] = true if n.Child != nil { if _, done := check[n.Child.ID]; !done { printID(n.Child) } } } printID(n) } func main() { n1 := Node{ID: 1} n2 := Node{ID: 2} n3 := Node{ID: 3} n1.Child = &n3 n2.Child = &n1 n3.Child = &n2 n := Node{ID: 4, Child: &n1} n.PrintID() }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golangサンプルコード:自己参照構造体のデータを再帰関数を使用してプリントする

今日書いたサンプルコード 自己参照構造体のデータを再帰関数を使用してプリントします。 マップを使って無限ループを回避。 package main import "fmt" type Node struct { ID int Child *Node } func (n *Node) PrintID() { check := map[int]bool{} var printID func(n *Node) printID = func(n *Node) { fmt.Printf("%d\n", n.ID) check[n.ID] = true if n.Child != nil { if _, done := check[n.Child.ID]; !done { printID(n.Child) } } } printID(n) } func main() { n1 := Node{ID: 1} n2 := Node{ID: 2} n3 := Node{ID: 3} n1.Child = &n3 n2.Child = &n1 n3.Child = &n2 n := Node{ID: 4, Child: &n1} n.PrintID() } 3000文字Tips - 知ると便利なTipsをみんなへ届けよう https://qiita.com/official-events/d523df99d6479293ffa7
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golangでタイピングゲームを作ってみた

はじめに Goの学び直しとして、最近はメルカリさんの「プログラミング言語Go完全入門」に沿って学習していて、そちらのお題であったタイピングゲーム(ターミナル上で遊べる)を作成してみました。 Demo ソース main.go package main import ( "bufio" "fmt" "io" "os" "strconv" "time" "github.com/tjarratt/babble" ) func main() { var ( ch_rcv = myInput(os.Stdin) t = 1 // タイムリミット tl = time.After(time.Duration(t) * time.Minute) // 制限時間処理 n = 0 ) // Babbleという、英文字をランダム生成してくれるライブラリを使用(英単語ではない) babbler := babble.NewBabbler() babbler.Count = 1 fmt.Println("Start the typing game." + " Time limit is " + strconv.Itoa(t) + " second." + " Yay, start!") for i := true; i; { // 英文字をランダムに生成し出力 q := babbler.Babble() fmt.Println(q) select { case <-tl: // 制限時間が来た時の処理 fmt.Println("Finished!" + " Your score is " + strconv.Itoa(n) + " points! Good job:)") i = false case x := <-ch_rcv: // お題と入力した値の比較処理 if x == q { fmt.Println("OK!") n += 1 } else { fmt.Println("NG :(") } } } } /* 標準入力をforの無限ループで受付け、 戻り値を受信専用のチャネル型に(最終的にselectで受信caseとして扱うため) */ func myInput(r io.Reader) <-chan string { ch := make(chan string) go func() { s := bufio.NewScanner(r) for s.Scan() { ch <- s.Text() } }() return ch } 工夫・苦戦した点 お題の生成方法 どのようにして英単語を自動生成すれば良いか検討がつかなかったが、ググっていくと、Babbleという英文字をランダムに生成してくれるライブラリがあったので、そちらを使うことに。Usageも詳しく記載あったので、そこからは早かったです。 標準入力の受付け もちろん入力を一度のみしか受付けないタイピングゲームは見たことがないので、入力があった場合は無限に受け付けるようにしないといけないですね。 そこでforを使い、Scan()して、入力が検知される限り、チャネル送信し、selectにて受付けるようにしました。 time.After引数に直接変数を代入すると・・・ time.After(xx * time.Minute)のxxの部分に、intを代入した変数を直接ぶっ込むと、下記エラーが出現。 invalid operation: second * time.Second (mismatched types int and time.Duration) 結論、こちらを参考にさせていただき解消。引用させていただくと、下記の通りでした。 time.After()ではtime.Duration型を受け付けますが, int型*Duration型は使えないみたいです。 そのため, 時刻処理にint型を使用する際にはtime.Duration()でラップしてやる必要があります。 最後に メルカリさんの「プログラミング言語Go完全入門」は本当にわかりやすく、各章の解説動画もあるので、大変ありがたいです。 今回はゴールーチン、チャネル、selectを中心に理解を深めていきましたが、contextの方が未だあやしいので、次はそちらを学習しながら、最終的にはフロントが少しだけリッチなアプリを作成できたらいいなと考えております。 最後までご拝読いただき、有難うございました。 ※まだ未熟なGopherなので、お気づきの点ございましたらコメント頂けますと幸いです。 参考 Babble golangの時刻処理におけるint型の取り扱い方 [Go言語/非同期処理]Go言語でタイピングゲームを作ってみた.go
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Goでタイピングゲームを作ってみた

はじめに Goの学び直しとして、最近はメルカリさんの「プログラミング言語Go完全入門」に沿って学習していて、そちらのお題であったタイピングゲーム(ターミナル上で遊べる)を作成してみました。 Demo ソース main.go package main import ( "bufio" "fmt" "io" "os" "strconv" "time" "github.com/tjarratt/babble" ) func main() { var ( ch_rcv = myInput(os.Stdin) t = 1 // タイムリミット tl = time.After(time.Duration(t) * time.Minute) // 制限時間処理 n = 0 ) // Babbleという、英文字をランダム生成してくれるライブラリを使用(英単語ではない) babbler := babble.NewBabbler() babbler.Count = 1 fmt.Println("Start the typing game." + " Time limit is " + strconv.Itoa(t) + " second." + " Yay, start!") for i := true; i; { // 英文字をランダムに生成し出力 q := babbler.Babble() fmt.Println(q) select { case <-tl: // 制限時間が来た時の処理 fmt.Println("Finished!" + " Your score is " + strconv.Itoa(n) + " points! Good job:)") i = false case x := <-ch_rcv: // お題と入力した値の比較処理 if x == q { fmt.Println("OK!") n += 1 } else { fmt.Println("NG :(") } } } } /* 標準入力をforの無限ループで受付け、 戻り値を受信専用のチャネル型に(最終的にselectで受信caseとして扱うため) */ func myInput(r io.Reader) <-chan string { ch := make(chan string) go func() { s := bufio.NewScanner(r) for s.Scan() { ch <- s.Text() } }() return ch } 工夫・苦戦した点 お題の生成方法 どのようにして英単語を自動生成すれば良いか検討がつかなかったが、ググっていくと、Babbleという英文字をランダムに生成してくれるライブラリがあったので、そちらを使うことに。Usageも詳しく記載あったので、そこからは早かったです。 標準入力の受付け もちろん入力を一度のみしか受付けないタイピングゲームは見たことがないので、入力があった場合は無限に受け付けるようにしないといけないですね。 そこでforを使い、Scan()して、入力が検知される限り、チャネル送信し、selectにて受付けるようにしました。 time.After引数に直接変数を代入すると・・・ time.After(xx * time.Minute)のxxの部分に、intを代入した変数を直接ぶっ込むと、下記エラーが出現。 invalid operation: second * time.Second (mismatched types int and time.Duration) 結論、こちらを参考にさせていただき解消。引用させていただくと、下記の通りでした。 time.After()ではtime.Duration型を受け付けますが, int型*Duration型は使えないみたいです。 そのため, 時刻処理にint型を使用する際にはtime.Duration()でラップしてやる必要があります。 最後に メルカリさんの「プログラミング言語Go完全入門」は本当にわかりやすく、各章の解説動画もあるので、大変ありがたいです。 今回はゴールーチン、チャネル、selectを中心に理解を深めていきましたが、contextの方が未だあやしいので、次はそちらを学習しながら、最終的にはフロントが少しだけリッチなアプリを作成できたらいいなと考えております。 最後までご拝読いただき、有難うございました。 ※まだ未熟なGopherなので、お気づきの点ございましたらコメント頂けますと幸いです。 参考 Babble golangの時刻処理におけるint型の取り扱い方 [Go言語/非同期処理]Go言語でタイピングゲームを作ってみた.go
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

golang playgroundをローカルで動かす方法

この記事に書いてある内容で実行できなかった場合は教えてください。 ここでも質問されているのですが、READMEに書かれている方法ではlocalで起動することが出来ません。 Gophersのslackで聞いたところ解決したので書いておきます。(その節はありがとうございました!) この手順に関してはREADMEを見るのではなく、Makefileを見ることで知ることが出来ます。 実行環境例 Ubuntu 20.04 LTS docker version $ docker version Client: Docker Engine - Community Version: 20.10.3 API version: 1.41 Go version: go1.13.15 Git commit: 48d30b5 Built: Fri Jan 29 14:28:23 2021 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.3 API version: 1.41 (minimum version 1.12) Go version: go1.13.15 Git commit: 46229ca Built: Fri Jan 29 14:31:57 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: v1.4.3 GitCommit: 269548fa27e0089a8b8278fc4fc781d7f65a939b runc: Version: 1.0.0-rc92 GitCommit: ff819c7e9184c13b7c2607fe6c30ae19403a7aff docker-init: Version: 0.19.0 GitCommit: de40ad0 repositoryをclone $ git clone https://go.googlesource.com/playground gVisorの準備 installする場合 [https://gvisor.dev/docs/user_guide/install/:title] 上記に記載してあるお好みの方法でインストール ※aptでinstallした場合はインストール後に runsc install コマンドを実行する必要がある。 gVisorを使いたくない(使えない)場合 gVisor(runsc)がインストールされていないとplaygroundのソースコードがそのままでは実行できない為、必要に応じて書き換えます。 playground/sandbox/sandbox.go cmd := exec.Command("docker", "run", "--name="+name, "--rm", "--tmpfs=/tmpfs:exec", "-i", // read stdin # runsc -> runcに書き換え "--runtime=runc", "--network=none", "--memory="+fmt.Sprint(memoryLimitBytes), *container, "--mode=contained") playground/sandbox/Makefile runlocal: docker dockergvisor docker network create sandnet || true docker kill sandbox_dev || true # rootlessDocker用 # /var/run/docker.sock -> /var/run/user/1000/docker.sockに書き換え docker run --name=sandbox_dev --rm --network=sandnet -ti -p 127.0.0.1:8080:80/tcp -v /var/run/user/1000/docker.sock:/var/run/docker.sock golang/playground-sandbox:latest --dev ローカル実行環境構築 1.基本となるdocker imageをビルド playground $ docker build -t golang/playground . 2.sandboxサーバ側起動 playground/sandbox $ make runlocal 3.clientサーバ側起動 playground $ make runlocal 4.playgroundに接続 http://localhost:8081/ おわりに 個人的には他人に何かのインストールを強要することは好きではないのでgVisorは好きじゃないです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む