Go関連のことを調べてみた2020年02月13日

Go関連のことを調べてみた2020年02月13日

Scannerを使って、任意の文字列で区切りながら読み込む方法(golang初心者の備忘録)

# Scannerを使って、任意の文字列で区切りながら読み込む方法 #

## 動機 ##

[Goならわかるシステムプログラミング](https://www.lambdanote.com/products/go)の3章を読んでいて疑問に思ったところ。
Scannerを使って読み込むとき

* 改行を区切り文字とするときは何もしなくてよい
* 単語単位(空白区切り)はbufio.ScanWordsをSplitに渡せばよい

が、任意の文字列の場合はどうすればよいかわからないため、調査した。
また、

* 区切り文字列を含む読み込み
* 区切り文字列を含まない読み込み

についても違いを調査した。

## 実装方法 ##

“`go
func(data []byte, atEOF bool) (advance int, token []byte, err error)
“`

* advance: 次回の読み込みが始まる開始位置
* token: 今回の読み込まれるデータ
* err: エラー

を実装して、Scanner.Splitに渡す。

## コード例 ##

### 区

元記事を表示

Go の gRPC で Redis のデータを削除 (Delete)

設定ファイル、サーバープログラム、クライアントプログラムの3つが必要です。

“`text
$ tree
.
├── redis_delete
│   └── redis_delete.proto
├── redis_delete_client
│   └── main.go
└── redis_delete_server
└── main.go
“`

設定ファイル
>redis_delete/redis_delete.proto
こちらと同じ
[Python の gRPC で Redis のデータを削除 (Delete)](https://qiita.com/ekzemplaro/items/451d253a277d6b9bece6)

サーバープログラム

“`go:redis_delete_server/main.go
// —————————————————————
//
// redis_delete_server/main.go
//
// Feb/11/2020

元記事を表示

Go の gRPC で Redis のデータを更新 (Update)

設定ファイル、サーバープログラム、クライアントプログラムの3つが必要です。

“`text
$ tree
.
├── redis_update
│   └── redis_update.proto
├── redis_update_client
│   └── main.go
└── redis_update_server
└── main.go
“`

設定ファイル
>redis_update/redis_update.proto
こちらと同じ
[Python の gRPC で Redis のデータを更新 (Update)](https://qiita.com/ekzemplaro/items/1e94293e0471504b0663)

サーバープログラム

“`go:redis_update_server/main.go
// —————————————————————
//
// redis_update_server/main.go
//
// Feb/11/2020

元記事を表示

Go の gRPC で Redis のデータを読む (Read)

設定ファイル、サーバープログラム、クライアントプログラムの3つが必要です。

“`text
$ tree
.
├── redis_read
│   └── redis_read.proto
├── redis_read_client
│   └── main.go
└── redis_read_server
└── main.go
“`

設定ファイル

“`text:redis_read/redis_read.proto

syntax = “proto3”;

package redis_read;

service Greeter {
rpc RedisRead (RedisRequest) returns (RedisReply) {}
}

message RedisRequest {
string key = 1;
}

message RedisReply {
string strjson = 1;
}
“`

サーバープログラム

“`go:redis_read_server/main.go
// ————————

元記事を表示

Go の gRPC で Redis のデータを作成 (Create)

設定ファイル、サーバープログラム、クライアントプログラムの3つが必要です。

“`text
$ tree
.
├── redis_create
│   └── redis_create.proto
├── redis_create_client
│   └── main.go
└── redis_create_server
└── main.go
“`

設定ファイル

“`text:redis_create/redis_create.proto

syntax = “proto3”;

package redis_create;

service Greeter {
rpc RedisCreate (RedisRequest) returns (RedisReply) {}
}

message RedisRequest {
string key = 1;
string strjson = 2;
}

message RedisReply {
string key = 1;
}
“`

サーバープログラム

“`go:redis_create_server/

元記事を表示

バッファなしチャンネル(unbeffered channel)のブロッキング(blocking)について

# バッファなしは同期通信する
バッファなし

“`golang
ch1 := make(chan int)
ch2 := make(chan int, 0)
“`

バッファあり

“`golang
ch := make(chan int, 1)
“`

バッファなしの場合は同期通信となるのでチャンネルに送信すると同時に受信しなければずっとそこでブロックしてしまう。そのため下記のようなコードは実行前にfatal errorとなってしまう。

“`golang
func main() {
ch := make(chan int, 0)
ch <- 1 // ここでブロックし続けてしまう fmt.Println("finish") } ``` 解決するにはどこかで受信しておかなければならない ```golang func main() { ch := make(chan int, 0) go func() { <-ch }() ch <- 1 fmt.Println("finish") } ``` # バッファありはcapacityまではブロックしない

元記事を表示

【go + gin + gorm】GAEとCloud SQL for MySQLを使ってデプロイしてみる

[【Go+Gin+Gorm】初心者だから超簡単webサービス作ってみる](https://qiita.com/dai-maru/items/7e97fc6623375c7eb14a)
[【go + gin + gorm】webアプリにログイン機能を追加してみる](https://qiita.com/dai-maru/items/f7cdd22baf3425a1722d)
続きです。

今回は、劣化版ツイッターアプリをGCPを使ってデプロイしてみるという内容です。
GCPで使うのは、`GAE standard環境`と、`Cloud SQL for MySQL`です。
コードは[github](https://github.com/daichiiyamada/mytweet-deploy)に上げています。

# `go modules`を使う
今回、GAEにデプロイするにあたって、`$GOPATH`周りでエラーが起こったので、`go modules`を使うことにしました。
`go modules`は依存モジュール管理ツールです。
Go では`GOPATH`という概念があって、Go のコー

元記事を表示

Golang x Beego x Docker x CircleCI x npmで開発環境をサクッと作ってみよう

DockerとCircleCIなどを組み込みつつGolangのBeego開発環境を構築します。
本稿では以下を前提とします。

**前提となる知識**
・terminalのコマンド操作
・viまたはエディタの操作
・Docker,docker-composeの知識
・gitやgithubの基本的な操作

**前提となる条件**
・OSはmacOSを前提とします。どうしてもWindowsなどの場合はVagrantでLinuxの仮想環境を立てるなどして自力で対応してみてください。
・バージョン管理のツールはGithubを用います。

**この記事で書いていること**
・Beegoの0からの環境構築
・Dockerとdocker-composeでコンテナ環境構築
・CircleCIの0からの設定
・フロントエンド環境の0からの構築

**この記事に書いてないこと**
・Go言語特有の実装方法やtipsなど

# Beego環境のセットアップ
## Goのインストールの確認
以下のコマンドでGoがローカルに入っているか確認しましょう。

`go version`

not foundと表示され

元記事を表示

JSON unmarshalやORMがreturnで結果を返すのではなく変数のポインタを使う理由

## はじめに

GoでJSONをデコードするとき、こんな感じに変数のポインタを渡しますよね。

“`go
var result SomeStruct
err := json.Unmarshal(b, &result) // ポインタを渡して結果を詰め込んでもらう
“`

rubyやpythonなら、JSONデコードってこんな感じですよね

“`ruby
# ruby
result = JSON.parse(some_json) # 入口からJSONが入って出口からパース結果が出てくる
“`

“`python
# python
result = json.load(some_json) # 入口からJSONが入って出口からパース結果が出てくる
“`

さて、なぜでしょうか。

## TL;DR

動的言語なら関数がどんな型を返しても良い訳です。
resultの型が何であっても、問題なく取り扱うことができます。
が、静的言語であるGoはそのようにはいきません。
同じようにresultを受け取る方式では、関数を利用する側は
取り出したい型がわかってるのに、取り出し後に毎回

元記事を表示

【Go】メソッドの定義方法サンプルメモ

### 基本の形

“`go
func (<レシーバー>) <関数名>([引数]) [戻り値の型] {
[関数の本体]
}
“`

### サンプル

“`go:sample.go
package main

import (
“fmt”
)

type myInt int

// 引数無し
func (i myInt) plusOne() myInt {
return i + 1
}

// 引数あり
func (i myInt) plus(j myInt) myInt {
return i + j
}

// レシーバーの変数名省略(呼び出し元の変数にはアクセスしない)
func (myInt) printHoge() {
fmt.Println(“Hoge”)
}

func main() {
var i myInt = 1
result := i.plusOne()
fmt.Println(result) // 2

var j myInt = 4
result2 := i.plus(j)
fmt.Println(result2) // 5

元記事を表示

【Go】関数の定義方法サンプルメモ

### 基本の形

“`go
func <関数名>([引数]) [戻り値の型] {
[関数の本体]
}
“`

### サンプル

“`go:sample.go
package main

import (
“fmt”
)

// 基本の形
func plus(a int, b int) int {
return a + b
}

// 戻り値無し
func printPlus(a int, b int) {
fmt.Println(a + b)
}

// 戻り値&引数無し
func printDummy() {
fmt.Println(“printDummy”)
}

// 戻り値複数
// 元の値と、足し算した値を返す
func plus2(a int, b int)(int, int, int){
return a, b, a + b
}

// 可変長引数
// アンダースコア変数
// https://qiita.com/penguin_dream/items/c1df36040b3fc6d42945
func printVariable(strs

元記事を表示

Go mapのkeyにインターフェースを使う場合に気をつけるべきこと

小ネタです。

## GoのMapのkey

goはmapの初期化時以下のように「keyの型」と「valueの型」を両方宣言しますが、

“`go
m := make(map[string]string)
“`

この「keyの型」には当然interface(空interface含む)を指定することもできる。

“`go
m := make(map[io.Reader]string) // これとか
m := make(map[interface{}]string) // これ
“`

このような場合、実際に値を入れるときに型が違えば当然keyも違う。

要するにこういうことです

“`go
type dog int
type cat int

m := make(map[interface{}]string)
m[dog(1)] = “dog dayo”
m[cat(1)] = “cat dayo”

fmt.Printf(“%v”, m) // map[1:dog dayo 1:cat dayo]
// 拡張int同士、同じ数字だがkeyは違う

“`

同じ

元記事を表示

ABC049C – 白昼夢を簡単に導く方法が知りたい(Golang)

##はじめに
[ABC049C – 白昼夢](https://atcoder.jp/contests/abs/tasks/arc065_a)を検索文字列の特性上、文字列をリバースして導く方法で解きました。
解きかたはさておき、検索能力の低さゆえ、Goに以下標準関数が見つけられず手作りとなってしまったので、検索能力向上した際には改良したいと思いメモです。

– 文字列のリバース
– 開始〜終了桁数を指定した文字列の抜き出し(例:abcを1文字目から2文字目で抜き出して「b」を求める)

##コード
“`golang
package main

import (
“fmt”
)

func main() {
var s string
annwer := “YES”
divide := [4]string{“dream”, “dreamer”, “erase”, “eraser”}
fmt.Scanf(“%s”, &s)

// リバース
for i :=0; i < len(divide); i++ { divide[i] = getReverse

元記事を表示

GoのサンプルWebアプリをローカルで実行した時にはまったことのメモ

# 背景
– [Goプログラミング実践入門](https://book.impress.co.jp/books/1115101145)に記載されている[サンプルWebアプリのコード](https://github.com/mushahiroyuki/gowebprog)をローカルで実行しようとしたときにはまったことのメモ

# やっていたこと
– ホームディレクトリに`git clone`してそのまま`go build`をした
– すると以下のエラーが

“`
route_main.go:5:2: cannot find package “chitchat/data” in any of:
/usr/local/Cellar/go/1.13.4/libexec/src/chitchat/data (from $GOROOT)
/Users/XXXXXX/go/src/chitchat/data (from $GOPATH)
“`
– route_main.goを見てみると、importで自プロジェクトのパッケージを呼び出しており、そこが悪さをしていそう

“`go
impor

元記事を表示

HackerRankの30Days of Codeで学んだことメモ

# [HackerRank](https://www.hackerrank.com/dashboard)とは
– 課題を通じてプログラミング言語を学習できるサイト
– 無料
– 扱っている言語は多数
– その中の30Days of Codeというカリキュラムに挑戦

# 背景
– Goの基本的な書き方を学ぶために始めます
– 初心者です
– 自分の解答やEditorialの内容を基に書きます

# Day1 Data Types

## ポイント
– 標準入力から整数、浮動少数点数、文字列を取得する

## メモ
– 標準入力の取得にはfmtパッケージの[Scanf関数](https://golang.org/pkg/fmt/#Scanf)が使える
– 引数にアドレスを指定することで、スペース区切りで順繰りに値を格納してくれる

“`:入力
12
4.0
“`

“`go
//標準入力取得用変数
var stdin_i uint64
var stdin_f float64

//標準入力から整数と浮動少数点数を取得
fmt.Scanf(

元記事を表示

Golang – Knuth-Durstenfeld Shuffle with crypto/rand

“`golang

package main

import (
“crypto/rand”
“fmt”
“math/big”
)

func shuffle(array []int) {
for i := len(array) – 1; i >= 0; i– {
result, err := rand.Int(rand.Reader, big.NewInt(int64(i+1)))

if err != nil {
panic(err)
}

j := int(result.Int64())

array[i], array[j] = array[j], array[i]
}
}

func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
shuffle(a)
fmt.Println(a)
}

“`

“`
[1 2 3 4 5 6 7 8 9 10]
[7 2 1 10 3 8 9 6 5 4]

[1 2 3 4 5 6 7 8 9 10]
[

元記事を表示

ABC081B – Shift onlyを2で割れる回数の最小値から導く方法(Golang)

##はじめに
[ABC081B – Shift only](https://atcoder.jp/contests/abs/tasks/abc081_b)を実際の操作のシミュレーションでのカウントではなく、
2で割れる回数の最小値から導く方法です。

“`golang
package main

import (
“fmt”
)

func main() {
var n int
min := 1000000000 // Aiの取りうる値の最大値
fmt.Scanf(“%d”, &n)
nums := make([]int, n)

// n個の値を取得
for i := 0; i < n; i++ { fmt.Scan(&nums[i]) } for i :=0; i < n; i++ { lcnt := 0; // 2で割り切れる限り回し続ける for nums[i]%2 == 0 { nums[i] = nums[i]/2 lcnt++ // 割った数をカウント }

元記事を表示

文系プログラマーがAtCoderをする前に確認するメモ

##はじめに
AtCorderを開始する前に確認する自分用メモです。
こちらの記事は、習慣的に過去問をこなしていくときのハードルをなくすことを目的としています。

なお、私はJAVA、PHPの経験が長いですが、
現在はQAを経て、外資系コンサルティングファームに所属しており日常コードに触れる機会はありません。

##前提(以下には触れていません)
– AtCorderへのアカウント登録
– コンテストが対象の方は、参加したいコンテストの参加登録と参加日の到来

##参加対象
例です。コンテストに参加する習慣がついている方はTOPから遷移できるかと思いますが、
過去問をこなしていこうと思っている方はどこからいくんだっけ、どこまで消化したっけと迷うくらいなら直リンクで飛びましょう。
URL:https://atcoder.jp/contests/abs/tasks
やっていることメモ:[AtCoder Beginners Selection](https://atcoder.jp/contests/abs)の10問目
参考:[競技プログラミングって何? (はじめての高校生向け)](htt

元記事を表示

WSL上でgolangを使ってMP3の情報を取得する

### go環境の用意
“`sh

$ git clone https://github.com/syndbg/goenv.git ~/.goenv
“`

`~/.bashrc` に追記

“`bash

export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
eval “$(goenv init -)”
“`

go のバージョン設定、確認

“`sh

$ goenv install 1.13.7
$ go version
go version go1.13.7 linux/amd64
“`

### id3-go を使ってMP3の情報を取得する

[GitHub – mikkyang/id3-go: ID3 library for Go](https://github.com/mikkyang/id3-go)

“`sh

$ go get github.com/mikkyang/id3-go
“`

サンプルコード

“`go

package main

import (

元記事を表示

goのioインターフェースを使ってみよう

# はじめに

こんにちわ、すえけん([@sueken5](https://twitter.com/Sueken51))です。

今回の記事ではgolangのioインターフェースを使うと効果的な処理がかけるようになるのでそれを紹介します。

# io.Reader/io.Writer

io.Reader/io.Writerはioパッケージで提供されているインターフェースです。
どこで使われているかというとbyte列をいじる際によく採用されています。よくみるところだと`encoding/json`や`os`パッケージのファイル周りで使われています。

# Benchmark

次の二つの関数のベンチマークを測ってみます。一つはreaderからbyteを取り出した後にmarshalし、もう一つはdecoderにFileインスタンスを渡しています。

“`
package io_bench

import (
“encoding/json”
“fmt”
“io/ioutil”
“os”
)

type test struct {
Message string `json:”me

元記事を表示

OTHERカテゴリの最新記事