Go関連のことを調べてみた2021年01月19日

Go関連のことを調べてみた2021年01月19日
目次

GoのHTTP実装を読んだ知見をまとめる~FIFOを5通りで実装する~

# はじめに
引き続き、GoのHTTP実装と絡めて書く。今日はFIFO実装について。
経緯は[こちら](https://qiita.com/behiron/items/78d023be96058224e583#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)

[Russ CoxによるHTTPクライアントのFIFO実装](https://github.com/golang/go/blob/682a1d2176b02337460aeede0ff9e49429525195/src/net/http/transport.go#L1242-L1306)が工夫されていて非常に興味深かった。
コメントを見ると、[Okasaki’s purely functional queue](https://www.amazon.co.jp/-/en/Chris-Okasaki/dp/0521631246)を元に、少し工夫したものらしい。

今回はそれらに触れた上でGoでFIFOを5通りの方法で実装していきたいと思う。

実装およびテストコードは[GitHub](https://gi

元記事を表示

Goでテストを書くために、まずinterfaceを設計するということ

## Goでテストコードを書くことになった場合に

あなたが、勤務先で上長から「テストコードを書いてください」と指示されたとき、
テストが書ける設計になっているでしょうか。

この記事では、**S3からファイルを取得して読み取る**というユースケースに対して
テストを書くことについて考えていきます。

## テストが書きづらいケース

“`main.go
var awssess = newSession()
var s3Client = newS3Client()

const defaultRegion = “ap-northeast-1”

func newSession() *session.Session {
return session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
}

func newS3Client() *s3.S3 {
return s3.New(awssess, &aws.Conf

元記事を表示

【Go】go-oidcを使ってOpen ID Connectを利用する

## Open ID Connect
– outh2の進化版でトークン発行の処理がある
– アプリケーション自体にユーザーパスワードなどの認証情報を持たせずに、別のプロバイダー(ここではGoogle)に委任する
– プロバイダーはいろいろある
– Google
– AzureAD
– AWS Cognito
– outh0
– `state`という概念があり、クロスサイトスクリプティングなどのなりすましを防止

## 公式パッケージ
https://github.com/coreos/go-oidc

## インストール

“`bash
git cloen https://github.com/coreos/go-oidc
“`

## exampleのREADMEの通りにセットアップする

“`
cd go-oidc/example
“`

“`
yuta:~/go-oidc/example (v3=) $ cat README.md
# Examples

These are example uses of the oidc packag

元記事を表示

【Golang】サポートする GOOS と GOARCH を一覧で確認するコマンド(ビルドの対応プラットフォーム確認)

> `go build` する際に指定可能な `$GOOS` と `$GOARCH` の一覧を**コマンドで確認**したい。

なんか、Go 言語のバージョンだけでなく環境によってもビルドできる(サポートされた)OS やアーキテクチャが異なるようだったので、シェル・スクリプトで事前にチェックしたいのです。

[「golang GOOS 一覧 確認 コマンド」でググって](https://www.google.com/search?q=golang+GOOS+%E4%B8%80%E8%A6%A7+%E7%A2%BA%E8%AA%8D+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)もピンポイントな記事が出てこなかったので、自分のググラビリティとして。

## TL; DR

> `go tool dist list`

## TS; DR

“`shell-session
$ go tool dist list
aix/ppc64
android/386
android/amd64
android/arm
…(以下省略)

$ go version
go

元記事を表示

Macでgqlgenのserver.goを起動するとファイアウォール警告が出る

GoのGraphQLサーバライブラリであるgqlgenの開発サーバ(GraphQL Playground)をMac上で起動すると、ファイアウォールの警告が出てしまってめんどくさい。
![20210108160313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/5e192904-6f03-13d6-85c8-5c0daf851b80.png)

通常はMacの環境設定のセキュリティとプライバシーのファイアウォール設定で例外を設定するのですが、うまくいかなかったので別の方法で解決します。

server.goの最後で次のようになっています。

“`go
log.Fatal(http.ListenAndServe(“:”+port, nil))
“`

これだと「0.0.0.0」でlistenするようです。0.0.0.0はすべてのネットワークインタフェースを指し、過剰です。

以下のように「localhost」まはは「127.0.0.1」を明示するように変更します。

“`go
log.Fa

元記事を表示

LINE Bot からDropboxに写真をアップロードする

タイトルの通り、LINE Bot からDropboxに写真をアップロードするシステムを作ってみました。現状は課題だらけですが、主要機能が実装できたので投稿します。

LINE Botに画像を送ると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951392/9964bfae-caa5-bcb8-6cda-0e575d2335c7.png)

Dropboxにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951392/215a2172-9836-91d7-5724-dac47a84a336.png)

ソースコード

“`go:main.go
package main

import (
“io”
“log”
“net/http”
“os”

“github.com/dropbox/dropbox-sdk-go-unofficial/dr

元記事を表示

go moduleを使う

## 環境変数で有効化する
“`
go env -w GO111MODULE=on
go env | grep MOD
“`

## 初期化処理

“`
go mod init test
“`

go.modが作成されている

“`go.mod
module test

go 1.13
“`

## 起動
自動的にgo getされていないパッケージがインポートされる

“`
go run main.go
“`

元記事を表示

Go.modの使い方

GOPATHを使っているとimport出来ないライブラリとか出てきて変なエラーが出てくる事があると思います。
GoModulesのgo.modを使えば解決するかもしれないので記載しておきます。

【環境】

windows10
VScode

ターミナルでgo envと打って設定を確認します

VScodeからターミナル→新しいターミナルで開いてgo envと打ち込みます。
ずらーっと色々設定が並んでくると思いますがその中の
“` GO111MODULE=“`
これがデフォルトだとonになっていないので設定をonにします。

GO111MODULE=をonにする

ターミナルで
“`go env -w GO111MODULE=on“`
と打ち込みましょう。
もう一度go envと打って確認すると
set GO111MODULE=onとなっているはずです。
※筆者はこの時、なぜかonにならず原因が分からなかったので
一度Go言語を再インストールしたところうまくいきました。

go.modを配置する<

元記事を表示

「世界一美しい数式」をプログラムで表現する

# はじめに

$e^{iπ} = -1$
は、「世界一美しい数式」といわれているオイラーの等式です。
確かに美しいというか無駄がないという感じですが、これをプログラムで出力してみたいと思いました。
ただ、それだけです。

とはいえ、一見簡単そうな数式ですが、プログラムで表現するのは少しだけ手間です。

* $e$や$π$といった無理数を扱う必要がある。
* 複素数を扱う必要がある。
* さらに、複素数のべき乗を扱う必要がある。

# 実行環境
オンラインでコンパイル可能な以下のいずれかで実行確認しました。
[Paiza.io](https://paiza.io/ja)
[TIO](https://tio.run)

# D言語の場合

* $e$は`E`、$π$は、`PI`という定数定義が`std.math`で用意されている。
* 複素数は、`complex`テンプレートが用意されている。
* べき乗は`^^`演算子を利用できる。

“`d:
import std;

void main()
{
auto x = complex(cast(real)0.0, PI);

元記事を表示

GoをHerokuにデプロイするときに Push rejected, failed to compile Go app. のエラー

# エラーについて
Goで作ったAPIをHerokuにデプロイしようと思い、
`git push heroku main`
コマンドをしたところ

“`
! Push rejected, failed to compile Go app.
! Push failed
“`
上のようなエラーで失敗。

# 解決した方法
ログを遡ってみると、

“`
—–>
!! The go.mod file for this project does not specify a Go version
!!
!! Defaulting to go1.12.17
!!
!! For more details see: https://devcenter.heroku.com/articles/go-apps-with-modules#build-configuration
!!
—–> New Go Version, clearing old cache
“`

のような記述があった。最初はこれが原因だとは思ってい

元記事を表示

キーエンス プログラミング コンテスト 2021のメモ

# 前置き

Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。

# 問題

https://atcoder.jp/contests/keyence2021

# A

“`Q_A.go
package main

import (
“bufio”
“fmt”
“os”
“strconv”
)

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int64 {
sc.Scan()
i, e := strconv.ParseInt(sc.Text(),10,64)
if e != nil {
panic(e)
}
return i
}

func main() {
sc.Split(bufio.ScanWords)

var N int
fmt.Scanf(“%d”, &N)

var a int64
var c int64
b := make([]int64,

元記事を表示

オレオレgoimportsを作ってみた

# やりたいこと、作ったもの

## `goimports`最高

`goimports`はGoのCLIツールで、`*.go`ファイルに対して↓を実行してくれます。

– `import`していない外部パッケージを`import`してくれる
– 使っていない`import`は削除してくれる
– 最後に`gofmt`もかけてくれる

## でも`goimports`は変な空行を入れてくる

[github.com/golang/go/issues/20818](https://github.com/golang/go/issues/20818) のIssueにある通り、`goimports`は変な空行を入れてきます。
こうなっている理由は単に「仕様が決まっていないから」で、Issueでも4年間くらい議論され続けています。

## 空行を最低限にする`goimports`を作った

こういう状況ならオレオレ`goimports`を自作するしかないだろうと思って作ってみました。

https://github.com/rinchsan/gosimports

どれだけ空行を入れていようが順番

元記事を表示

DATA-DOG/go-txdbでDB接続を含むテストを楽に書こう

# DB接続を含むテストはツライ

– テスト用のデータをテストケースごとに用意しないといけない。
– DBの変更結果が他のテストケースに影響を与えないようにリセットしないといけない。
– DBへの変更が他のテストケースに影響を与えるので並列実行できない。

# DATA-DOG/go-txdbを使うと改善できる

– [DATA-DOG/go-txdb](https://github.com/DATA-DOG/go-txdb) で生成することのできるDBコネクションには↓のような特徴があります。
– `sql.DB`と互換性がある。
– すべてのクエリが独立したトランザクション内で実行される。
– `.Close()`を呼ぶとそのトランザクション内で実行されたクエリがすべてRollbackされる。
– これをうまく使うと、テストケースごとに独立したトランザクション内でクエリを実行することができ、テスト終了後にDB変更がRollbackされるので、テストケースごとのデータ処理が必要なくなり、他のテストケースへの影響もなくなるのでテストを並列実行することができます。
– 実際

元記事を表示

[Mac OS Big Sur]でGOの開発環境を作る

GOを使う必要があったため、Mac OS Big Surで環境を作りました。

##内容
– goenvのインストール
– goのインストール

## goenvのインストール

当初、`brew install goenv`でインストールしてみたいのですが、
バージョンが古るかったため、Gitでインストールしました。

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

シェルはzshを使っているので、環境変数を設定します。

“`zsh
% echo ‘export GOENV_ROOT=”$HOME/.goenv”‘ >> ~/.zshrc
% echo ‘export PATH=”$GOENV_ROOT/bin:$PATH”‘ >> ~/.zshrc
% echo ‘eval “$(goenv init -)”‘ >> ~/.zshrc
“`

シェルを再起動し環境変数を反映します。

“`zsh
% exec $SHELL
“`

goenvのバージョンを確認します。

“`zs

元記事を表示

Goで現在時刻のテストどうする話(めっちゃ薄いライブラリ作った)

# どういう記事?
現在時刻が絡むテストってGolangではどうするんだろうと思い調べた。
しっくりくるのがなかったので欲しい機能だけ入れたライブラリを作った。

# 調べた内容

@tomtwinkle さんの記事:[[Golang]テスタブルな現在時刻取得処理を作る](https://qiita.com/tomtwinkle/items/4dee6ed4e81784c66cd2) では以下3つの方法が紹介されてた。

* monkey.Patch
* flextimeパッケージ
* contextで引き回す

他には[Kentaro Kawanoさんの資料](https://www.slideshare.net/kawaken/golang-testingfortime-77668188) も参考になった。

* clockパッケージ
* 外部からの注入

でも、なんか、こう、もっと簡単でいいだよなー。。。

# 作ったもの

って思ってめっちゃ薄いライブラリ作ってみた。
https://github.com/bubusuke/xtime

## 考えたこと
flextimeやc

元記事を表示

GoでDropbox API v2を使ってみる

タイトルの通り、DropboxAPIを使ってみました。

手始めにgo getする

“`
go get github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/…
“`

ファイルをアップロードするサンプルコード

インスタンスを作って、ファイルをアップロードする処理となっています。

“`go
import “github.com/dropbox/dropbox-sdk-go-unofficial/dropbox”
import “github.com/dropbox/dropbox-sdk-go-unofficial/dropbox/users”

func main() {
config := dropbox.Config{
Token: “<取得したアクセストークン>“,
}
dbx := users.New(config)

req := files.NewCommitInfo(“<ファイルのアップロード先>“)
f, _ := os.Open(“<アップロードしたいフ

元記事を表示

Go言語チートシート

# 概要

goを書いていてよく使う割によく忘れる処理まとめ

## Context

~~~go
import (
“context”
)

ctx := context.Background()

ctx, cancel := context.WithCancel(ctx)
defer cancel()

~~~

### タイムアウト処理

~~~go
package main

import (
“context”
“time”
“log”
)

func main(){
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Second * 1)
defer cancel()

go func(){
// too many time function
time.Sleep(time.Second * 10)
}()

<-ctx.Done() log.Println("done") } ~~~ ## 環境変数 参照する変数が少数なら普通に`o

元記事を表示

【自己学習用】はじめてのGo1

#参考元

[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)
[Qiita Markdown 書き方 まとめ](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
qiitaに書くのは初めてなのでMarkdown記法もついでに学習。
[はじめてのGo](https://gihyo.jp/dev/feature/01/go_4beginners/0001)

#Go言語の特徴
– 2009年にGoogleにより発表されたオープンソースのプログラミング言語
– シンプルな言語仕様であるため学習が比較的容易
– 豊富な標準パッケージが同梱されている
– 巨大なコードでも高速にコンパイルできる
– Windows,OS X,Linuxなどの環境に合わせた実行ファイルを生成するクロスコンパイルのしくみがある

元記事を表示

LINEBotで画像、動画、位置情報を受けとったら処理を実行する@Go

以前作ったオウム返しするLINEBotをいじくり回しました。
https://qiita.com/endo-yuki/items/1a0ddfe857674be6044b
ドキュメントを参考にして、画像、動画、位置情報を受けっとったとき、メッセージを返す処理を追加しました。
https://pkg.go.dev/github.com/line/line-bot-sdk-go/linebot#TemplateAction

サンプルソースコード

“`go:main.go
~~~~~~~~~~~~~~(省略)~~~~~~~~~~~~~~~~~~~~~~
case *linebot.ImageMessage:
if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(“画像ですね”)).Do(); err != nil {
log.Print(err)
}
case *linebot.VideoMessage:
if _, err = bot.

元記事を表示

Go + Air でホットリロード

# はじめに
Goでファイル変更したときにホットリロードさせるツールとして、
[cosmtrek/air](https://github.com/cosmtrek/air)を使ってみたいと思います。

# 環境
go: v1.15.3

# プロジェクト作成
“`zsh
% mkdir sample && cd sample
% go mod init
% go mod init sample
“`

特にここはなんでも良いですが、フレームワークとして[gin](https://github.com/gin-gonic/gin)を使います。

“`zsh
% go get -u github.com/gin-gonic/gin
% vi main.go
“`

“`go
package main

import “github.com/gin-gonic/gin”

func main() {
r := gin.Default()
r.GET(“/”, func(c *gin.Context) {
c.JSON(200, gin.H{
“mess

元記事を表示

OTHERカテゴリの最新記事