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

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

Go言語でnewとmakeを使ってみた

##はじめに
Go言語でnewとmakeを使い、違いを備忘のために記します。

##環境
macOS Catalina 10.15.3
go1.13.3 darwin/amd64

##1. makeを使う
以下はmakeを使用して、変数を初期化する例です。コードは一部抜粋します。

“`sample.go
s := make([]int, 0)
m := make(map[string]int)
ch := make(chan int)

fmt.Printf(“%T\n”, s)
fmt.Printf(“%T\n”, m)
fmt.Printf(“%T\n”, ch)
“`

###[出力結果]
“`
[]int
map[string]int
chan int
“`

##2. newを使う
以下はnewを使用して、変数を初期化する例です。コードは一部抜粋します。

“`sample.go
var p *string = new(string)
var str = new(struct{})

fmt.Printf(“%T\n”, p)
fmt.Printf(“%T\n”

元記事を表示

アプリ実装者のためのGo1.13からのエラーとの付き合い方

# はじめに

[Go1.13から機能追加されたエラー](https://golang.org/doc/go1.13#error_wrapping)に関してキャッチアップがまだできていないアプリケーション開発者のための記事です。

# TL;DR

アプリケーション実装者は以下をすることで嬉しさを得られます。

* `fmt.Errorf(“%w”, err)` または `Unwrap() error`を実装したエラー型をカスタムエラーにする。
* `errors.Is`関数、`errors.As`関数を使いエラーハンドリングの受け口を実装する。

Go1.12までのバージョンとの実装方法の比較は[Go 1.13時代のエラー実装者のお作法](https://qiita.com/shibukawa/items/e633e426a6e67ea2e830)の記事が非常に参考になります。

### 環境

“`
$ go version
go version go1.13.1 darwin/amd64
“`

# ライブラリが提供するエラーとの付き合い方

## ライブラリが返すエラー値

元記事を表示

【Go】配列のサンプルメモ

“`go
package main

import (
“fmt”
)

func main() {
// 配列の型
// [長さ] 要素型
// [長さ] 要素型 {要素の初期値..}

// 配列の宣言
var arr1 [2]string
arr1[0] = “a”
arr1[1] = “b”
fmt.Println(arr1)

// 配列初期化
arr2 := [2]string{“a”, “b”}
fmt.Println(arr2)

// https://yttm-work.jp/lang/go/go_0005.html#head_line_03
var arr3 [2]string = [2]string{“a”, “b”}
fmt.Println(arr3)

// 初期値で指定した要素の数が自動的に長さとなる
arr4 := […]string{“a”, “b”}
fmt.Println(arr4)
}
“`

元記事を表示

【Go】スライスのサンプルメモ

“`go
package main

import “fmt”

func main() {
// 配列
arr := [3]string{“a”, “b”, “c”}

// スライス型の変数を宣言
var s1 []string
// スライス
s1 = arr[:]
fmt.Println(s1) // [a b c]

// var を使わないVersion
s2 := arr[:]
fmt.Println(s2) // [a b c]

// インデックスを指定
s3 := arr[1:2]
fmt.Println(s3) // [b c]

s4 := arr[1:3]
fmt.Println(s4) // [b c]

// append
s5 := append(s4, “d”, “e”)
fmt.Println(s4) // [b c]
fmt.Println(s5) // [b c d e]

// 配列とスライスを同時に宣言
s6 := []string{“A”, “B”, “C”}
fmt.Println(s6)

元記事を表示

Go + echo + Docker + VSCode + Remote Containers で開発環境の構築 (ホットリロードとステップ実行対応)

## 背景
– Go + echo で api サーバーを実装するにあたり開発環境を構築した際のメモ。
– Docker で動かしたい。
– VSCode の Remote Containers を試したい。
– ホットリロード欲しい。
– ステップ実行したい。

## 成果物
– https://github.com/f-sugar/golang-docker

## ホスト
– Docker 19.03.1
– docker-compose 1.24.1
– VSCode 1.42.0
– ms-vscode-remote.remote-containers 0.101.0

## コンテナ内
– go 1.13.7
– realize 2.1
– delve 1.4.0
– echo 4.1.14

## Dockerfile + docker-compose 作成
“` :Dockerfile
FROM golang:1.13.7

WORKDIR /go/src/app

ENV GOPATH /go

RUN apt-get update \
&& a

元記事を表示

Mac環境でgodocをインストールできなかった時にしたこと

以下コマンドでgodocをインストールしようとしたら

“`go
go get golang.org/x/tools/cmd/godoc
“`

`operation not permitted`が表示され、インストールできない。。。

[stackoverflowに似た現象](https://stackoverflow.com/questions/48617574/go-install-command-results-in-open-bin-palindrome-operation-not-permitted-in-m)に遭遇した人が。

以下手順で解決した。

“`
brew install go
mkdir Go
cd Go && mkdir bin pkg src
“`

元記事を表示

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

元記事を表示

OTHERカテゴリの最新記事