- 1. Goのnet/httpの実装をちょっと読んでみる
- 2. Adafruit Trinket M0でTinyGo
- 3. サードパッケージを使用したGoのアプリケーションをHerokuにデプロイする v2
- 4. govendorで依存関係のファイルが取得できないエラーについて
- 5. goenvでGolangのバージョン管理(最新版のGolangを使う)
- 6. Go Basic認証
- 7. C++, Go, Julia, Kotlin, Rust, Swift5 で競争
- 8. Go 1.13 以降で発生する 410 Gone への対応
- 9. golangのormであるxormを使ってみた
- 10. プログラムの複雑さを下げるため、条件分岐を減らす方法を考える
- 11. GoのechoでRESTAPIを作る時にCORSで怒られた時の対処法
- 12. Prometheus+Grafanaでk8s上のGoアプリケーションのメトリクスを回収して可視化
- 13. golangのmongo-go-driverを使うとstructのtime.TimeにUTCで日付が入るのでlocal-timeにする方法
- 14. 最も簡単にパワフルなGolangのvim開発環境をSpaceVimで構築する
- 15. 関数とメソッドの違い【golang】
- 16. ランダムに抽選する関数の確率テスト(Golang)
- 17. 自分なりのGoアプリケーションDockerfileのベストプラクティス
- 18. Go言語製 抽選Botの精度が怪しいので検証してみた話
- 19. Golang製のSlackAPI(nlopes氏の)がレポジトリ引っ越したらしい(´・ω・`)
- 20. leet code 83 Remove Duplicates from Sorted List の覚え書き
Goのnet/httpの実装をちょっと読んでみる
# はじめに
Goは標準パッケージとしてHTTPサーバが組み込まれており、`net/http` パッケージを用いると簡単にHTTPサーバを動かすことができます。今回は `net/http` パッケージの一部(HTTPサーバの内容)の実装を読むことで、HTTPサーバが動く裏側をざっと見てみたいと思います。困ったら [公式ドキュメント](https://golang.org/pkg/net/http/) を見ましょう。
なお、読んでいるコード Go1.13 のものです。
# Doc
まずざっと公式ドキュメントに書いてあるサンプルとドキュメントを眺めて、仕様をおさらいしておきます。
## `type Handler`
> ハンドラはHTTPリクエストに対してレスポンスを返します。
>
> ServeHTTPはレスポンスヘッダーとデータをResponseWriterに書き込んでからreturnする必要があります。リクエストが終了したことを示すシグナルを返します。ServeHTTP呼び出しの完了後または完了と同時にResponseWriterを使用したり、Request.Bodyを読
Adafruit Trinket M0でTinyGo
#はじめに
Goで組み込み向けプログラミングができるTinyGoが盛り上がってきているようなので試してみた。
今回実行したのは搭載LEDを利用したLチカ。
#動作環境
* OS: macOS 10.15.3
* Go: 1.13.8
* TinyGo: 0.12.0
* マイコン: Adafruit Trinket M0#セットアップ
###Go
“`
$ brew update
$ brew install go
“`
###TinyGo
“`
$ brew tap tinygo-org/tools
$ brew install tinygo
$ brew tap osx-cross/avr
$ brew install avr-gcc avrdude
$ go get -u tinygo.org/x/drivers
“`
###BOSSA
[BOSSA](https://github.com/shumatech/BOSSA/releases)からMAC用パッケージをダウンロードしてインストール
#実行コード
“`go:main.go
package mainimp
サードパッケージを使用したGoのアプリケーションをHerokuにデプロイする v2
以前書いた記事がGoのアップデートと共にゴミ記事と化したので別アプローチを記録
[サードパッケージを使用したGoのアプリケーションをHerokuにデプロイする](https://qiita.com/matopenKW/items/d1798a2f60bffdf719a8)結論から言うとgovendorをやめて、go modulesを使用する
#Goでアプリケーションを作成
Goアプリケーションの作り方は前回の作り方とほぼ同じ“`:main.go
package mainimport (
“github.com/gin-gonic/gin”
)type User struct {
Name string
Age int
}func main() {
router := gin.Default()
// css、js などの静的ファイルを読み込む場合。今回は使用しない。
// router.Static(“/assets”, “./assets”)router.LoadHTMLGlob(“templates/*.html”)
router.
govendorで依存関係のファイルが取得できないエラーについて
以前、govendorを使用してHerokuにデプロイするやり方を記事にしました。
[サードパッケージを使用したGoのアプリケーションをHerokuにデプロイする](https://qiita.com/matopenKW/items/d1798a2f60bffdf719a8)12月くらいにまたHerokuにアプリケーションをデプロイしようとした時にエラーが起きた。
書いた記事が1ヶ月でゴミ記事と化した…## 事象
とりまHerokuのエラーログ抜粋“`
remote: —–> Fetching any unsaved dependencies (govendor sync)
remote: —–> Running: go install -v -tags heroku .
remote: vendor/github.com/gin-gonic/gin/binding/default_validator.go:11:2: cannot find package “github.com/go-playground/validator/v10” in any
goenvでGolangのバージョン管理(最新版のGolangを使う)
`golang` を使った開発のため、バージョン管理を導入したときの手順を書きます。
## goenv について
**goenv** は Golang のバージョン管理ツールです。
https://github.com/syndbg/goenv
pyenv や rbenv など、他のバージョン管理ツールと同じようなものです。
## 環境情報
* macOS Catalina 10.15.3
* zsh 5.7.1 (x86_64-apple-darwin19.0)## goenv インストール
goenv のソースをリポジトリから取得する。
“`console:zsh
$ git clone https://github.com/syndbg/goenv.git ~/.goenv
“`次は bash の場合 `.bashrc`、zsh の場合 `.zshrc` の設定をしていきます。
## goenv パス設定
`goenv` を使うためのパスを通します。
### .zshrc
“`.zshrc:.zshrc
…
export GOENV
Go Basic認証
HTTP Basic認証の概要とGo標準パッケージ`net/http`を用いた実装をまとめる。
## BASIC認証とは
HTTPで定義される認証方式の一つ。
クライアントは、クライアントID(ユーザー名)とクライアントシークレット(パスワード)の組み合わせをコロン “:” でつなぎ、Base64エンコードした値を、Authorizationヘッダーにセットしてサーバーへ送信する。
これをサーバー側は受け取り、事前に登録されたクライアントIDとクライアントシークレットの組み合わせに一致するか検証する。一致した場合は、リクエストを処理する。一致しなかった場合は、ステータスコード401を返却する。
## Go標準パッケージ`net/http`での実装### クライアント側
“`go:client.go
package mainimport (
“fmt”
“io/ioutil”
“log”
“net/http”
“time”
)func main() {
// クライアント生成
client := &http.Client{Timeout: time.Du
C++, Go, Julia, Kotlin, Rust, Swift5 で競争
計算が速そうな6つの言語で、競争してみた。
種目は、64bit 整数を固定小数点数として使ったマンデルブロ集合の計算。
マシンは MacBook Pro (Retina, 15-inch, Mid 2015)。つまり、x86-64。## ソースコード
全部乗せると長いので、一番短くなった Kotlin のを載せる:
“`kotlin:kotlin
fun isMandel(rep: Int, lim: Long, x: Long, y: Long): Boolean {
var zr = 0L
var zi = 0L
for (i in 0 until rep) {
val zrNext = zr * zr / lim – zi * zi / lim + x
val ziNext = zr * zi * 2 / lim + y
val dist2 = zrNext * zrNext / lim + ziNext * ziNext / lim
if (4 * lim < dist2) {
Go 1.13 以降で発生する 410 Gone への対応
GOPRIVATE環境変数にリポジトリ名を設定する。
下記のような感じで、zshrcとかのシェルの設定ファイルに書く必要がある。“`
export GOPRIVATE=”github.com/hiko1129/macrotrends”
“`
golangのormであるxormを使ってみた
# はじめに
– こんにちはRIN1208です。今回はgolangのormであるxormに触れてみたのでそちらについて書いていきたいと思います。# 実行環境
– DockerCompose
– Goの実行環境 ver.1.13
– VScode(お好みのエディタ)以上の環境がある前提で書かせていただきます
# コンテナを立てる
“`docker-compose.yml
version: “3”
services:
mysql:
image: mysql:5.6
container_name: some-mysql
restart: always
environment:
– MYSQL_ROOT_PASSWORD=root
– MYSQL_DATABASE=hoge
command: >
–character-set-server=utf8mb4
–collation-server=utf8mb4_general_ci
–innodb_file_per_table
プログラムの複雑さを下げるため、条件分岐を減らす方法を考える
## はじめに
if分岐を減らすコードの有用性⇒なぜか三項演算子の話に置き換えられるってのをTwitterで見かけたので、実例を挙げてみました。
言語に寄らない知識なので使う言語はなんでもいいのですが、私が今使っているgolangで説明させていただきます。### なんで条件分岐が少ないと嬉しいのか?
個人的には、頭に優しくなるのが一番のメリットだと思っています。– 頭に優しい
– どこに分岐があるのかを考える箇所が減る
– 今なんの分岐中なのか?を考える箇所が減るもう少し客観的な理由をまとめます。
#### 影響範囲の複雑さを減らす
分岐処理がいたるところにあると、分岐処理が増えた時にいたるところに手を入れる必要があります。
しかし、これが分岐を減らして特定の場所に分岐がまとまっていくと、結果分岐に影響するコードの範囲が減ります。
疎結合なコードを作るのは大事ですよね#### テストの複雑さを減らす
テスト設計、皆さんどうしていますか?
テスト観点には以下があります。– 中身を気にしないブラックボックステストの網羅性(入力パターンを如何に網羅する
GoのechoでRESTAPIを作る時にCORSで怒られた時の対処法
フロントエンドとバックエンドでドメインが違う場合、フロントエンドからバックエンドにfetchするとCORSで怒られる。
その際は以下のようにCORSWithConfigミドルウェアを設定してやればいい。“`server.go
e := echo.New()
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{“http:///*リクエスト送る側のurl*/”},
AllowHeaders: []string{“authorization”, “Content-Type”, “Access-Control-
Allow-Origin”},
AllowCredentials: true,
AllowMethods: []string{http.MethodGet, http.MethodPost},
}))e.POST(“/login”, login)
e.GET(“/logout”, logout)e.Logger.Fat
Prometheus+Grafanaでk8s上のGoアプリケーションのメトリクスを回収して可視化
Prometheus+Grafanaで、k8s上で動かしているGoアプリケーションのMemoryやゴルーチン起動数などのメトリクスを回収し可視化する
# 最終的なグラフ
![](https://user-images.githubusercontent.com/19891114/71416134-8bc93c00-26a2-11ea-813f-195ab8c1bdd7.png)
# 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129577/6e593532-a986-3347-738b-45420c420773.png)
この記事では、Prometheus, Grafanaもk8s内で動作させます。
メトリクスの回収としては、GoのアプリケーションにPrometheus Exporterを入れてメトリクスを公開し、Promehteusはサービスディスカバリを使って、そのメトリクスを回収という挙動になります。# 構築
## kubernetesクラスタを立ち上げる
golangのmongo-go-driverを使うとstructのtime.TimeにUTCで日付が入るのでlocal-timeにする方法
“`go
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
opt := options.Client().ApplyURI(“mongodb://localhost:27017”)// findでstructにtime.Time型が設定されている状態で、取得するとUTCで設定されるのでLocalTimeZoneになるようにした。
rb := bson.NewRegistryBuilder()
// v1.2.1より前
// rb.RegisterDecoder(reflect.TypeOf(time.Time{}), bsoncodec.NewTimeCodec(bsonoptions.TimeCodec().SetUseLocalTimeZone(true)))
// v1.3.0以降 メソッドが変更になっている。。。
rb.RegisterTypeDecoder(reflect.TypeOf(time.Time{}), bsoncodec.NewTimeCodec(bsonoptions
最も簡単にパワフルなGolangのvim開発環境をSpaceVimで構築する
## はじめに
Vimでgolangを書く環境を整えたいと思っていたところ、SpaceVimを使ってそれがとても簡単にかつ満足度高く実現出来たので書いていきたいと思います。
> 前提としてSpaceVimが適用されていることが前提となりますので、インストールされていない方は、[こちら](https://qiita.com/sayama0402/items/5a9621ee58cf5255d254)で設定を行なってください。
> Golangのインストールなどについても解説しません。## layersの追加
[このlayer](https://spacevim.org/layers/lang/go/)を使います。
`~/.SpaceVim.d/init.toml`に以下の記述を追加します。
“`toml
[[layers]]
name = “lang#go”
“`一度保存して、vimを開いてください。
vimのnormalモードで以下を実行します。“`vim
:GoInstallBinaries
“`上記実行後、gotagsをインストールするため
関数とメソッドの違い【golang】
# オブジェクト指向言語では
# 関数
– オブジェクト関係なく、呼ぶと何か処理をする`プログラムの部品`# メソッド
– オブジェクト指向で登場する用語で、`オブジェクトの動作を定義したもの`らしい。# golangはオブジェクト指向??
– golangを勉強し始めて1週間。
– 今まで、同義的に使っていたメソッドと関数という言葉・・・
– golangがオブジェクト指向なのかはよくわからない([オブジェクト指向言語としてGolangをやろうとするとハマること](https://qiita.com/shibukawa/items/16acb36e94cfe3b02aa1))けど、まとめてみたらオブジェクト指向言語っぽく使えることを理解した。
– とにかく、**関数とメソッドは明確に違いがあるらしい**とのことでまとめてみた
– 諸先輩方、認識が違ったらご指摘お願いいたします。
– ※比較しやすいよう同じ処理をする# 関数
– `func`で始まる処理の塊の中で構造体(型)に紐づけられていないもの“`go:main.go
type Square struct {
ランダムに抽選する関数の確率テスト(Golang)
自作した社員抽選Slack Botの抽選確率がランダムになっているか調査するテストを書いてみました
> Go + AWS LambdaでSlackの社員抽選botを作った話
https://blog.acall.jp/2019/11/develop-slack-lottery-bot/## テスト対象関数
“`go:main.go
package mainimport (
“math/rand”
“time”
)func lotteryOneUserFromUsers(userIDs []string) string {
rand.Seed(time.Now().UnixNano())
userID := userIDs[rand.Intn(len(userIDs))]
return userID
}
“`
スライスを渡すと要素の1つがランダムで返ってきます
とてもシンプルな関数です## テストコード
“`go:main_test.go
package mainimport (
“fmt”
“math”
“testing”
)func
自分なりのGoアプリケーションDockerfileのベストプラクティス
最終的に作成されるDocker Imageが軽量になること
Docker Buildにかかる時間を短縮するを目標としている
## フォルダ構成
“`bash
$ tree .
.
├── Dockerfile
├── Makefile
├── pkg_a
│ ├── pkg_a.go
│ └── pkg_a_test.go
├── pkg_b
│ ├── pkg_b.go
│ └── pkg_b_test.go
├── go.mod
├── go.sum
├── main.go
“`標準的なGoアプリケーションの構成
ライブラリ管理はGo Modulesを使います。## Dockerfile
Dockerfileは以下のようになっています。
工夫点はコメントで番号つけてます。詳細は後述します“`Dockerfile
# ①
FROM golang:1.13 as builder# ②
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
WORKDIR /go/<アプリのリポジトリ名>#
Go言語製 抽選Botの精度が怪しいので検証してみた話
# いきさつ
ACALL株式会社では、slackで抽選をするbotがあって、会議のファシリテーターとか
誰か担当を決めるときにそのbotを使って決めています。Go + AWS LambdaでSlackの社員抽選botを作った話
https://blog.acall.jp/2019/11/develop-slack-lottery-bot/こんな感じで当選するのですが、
このbotの精度がどうも怪しい。
私と弊社CTOがやたら当選する気がする!Golang製のSlackAPI(nlopes氏の)がレポジトリ引っ越したらしい(´・ω・`)
ちょうどSlackBotの開発をしていたところ気がついたのでメモ。
## 旧レポジトリ( 2020年2月27日時点 )
“`
レポジトリURL: https://github.com/nlopes/slack
“`## 新レポジトリ( 2020年2月27日時点 )
“`
レポジトリURL: https://github.com/slack-go/slack
“`## README( nlopes/slack )
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195292/8219701b-187f-be3f-9842-4b7ffee11517.png)
上記は2020年2月27日時点の `nlopes/slack` のREADMEですが以下の
>but no guarantees are made on how up to date it will be
からとりあえずこれから入るアップデートが必要な機能とかは保証されないうんぬんでちゃんと新レポジト
leet code 83 Remove Duplicates from Sorted List の覚え書き
83 Remove Duplicates from Sorted List
https://leetcode.com/problems/remove-duplicates-from-sorted-list/この問題が曲者すぎた。
ぱっと見で簡単やろうと思った自分を殴りたい。激ムズでっせ。
ListNodeの値は[1,1,3]“`golang
func deleteDuplicates(head *ListNode) *ListNode {cur := head
for cur != nil && cur.Next != nil {
if cur.Val == cur.Next.Val {
cur.Next = cur.Next.Next //これでheadも更新済みfmt.Println(head, “headそのもの”)
fmt.Println(head.Next, “head.Next”)
fmt.Println(cur.Next, “cur.Next”)
} else {
cur = cur.Next
//ここでc