- 1. Go.spec.goからOpenAPI specの出力実験
- 2. REST APIを実装して遊ぶ
- 3. 値レシーバとポインタレシーバの違いについての備忘録(new UserとUser{}を使った場合について)
- 4. Raspberrypi Pi4にgo言語のインストール
- 5. Vectyを使ってGoでフロントエンドを作ってみた話
- 6. Go httpサーバー&リソースをワンバイナリにする
- 7. Go (Golang) コマンドラインツールの作り方
- 8. Go言語でAWS上、マスターデータ管理システムを実装した話
- 9. Goでカタカナバリデーションを実装しようとしたが、unicodeパッケージのKatakanaテーブルには記号なども含まれていた。
- 10. Goでプリミティブなアトミック操作をするならuber-go/atomicを使ってほしい話と、比較不能かつコスト0な型の話
- 11. Javaで飯食ってるエンジニアがGolangを学んでみる~序章~
- 12. Goで Chokudai SpeedRun 001 を解く
- 13. 初心者による初心者のためのGo|製作途中だからどんどん書き加えていくよ
- 14. Go言語のechoフレームワークを使用してAPIサーバーを立てる方法(入門)
- 15. OpenAPI等のジェネレータツールによる更新作業の自動化、失敗時の自動ロールバックの実現
- 16. Docker とVisual Studio Code を使った Go (Golang) 開発環境構築
- 17. deferの即時評価
- 18. 【Golang】mapに複数のキーを設定する
- 19. HandleFuncとHandleでは何が起きてる?違いは?
- 20. Gomega エラーメッセージが分かりやすいEqual Matcherを作った
Go.spec.goからOpenAPI specの出力実験
# はじめに
OpenAPI spec書くのきついよね。
ソースで書きたいじゃん。
ということで、実際にやってみた。## input
“`go
package apitype Error struct {
Code int32
Message string
}type NewPet struct {
Name string
Tag string
}type Pet struct {
NewPet
Id int64
}type FindPetsParams struct {
Tags []string
Limit int32
}type Interface interface {
// (GET /pets)
FindPets(params FindPetsParams) []Pet// (POST /pets)
AddPet(body Pet) Pet// (DELETE /pets/{id})
DeletePet(id int64)// (GET /pets/{id})
FindPetById(id
REST APIを実装して遊ぶ
# はじめに
最近Goしている。
RESTで遊んでいる。
OpenAPIで自動生成でやる。
書いてられない……
さて、どうしよう……# 解決案
ざっくり案だけど、JavaのSpringdocみたいに自動で仕様書書くのはどうだろう。
Goだと割と楽にコード解析ができる。
そこで、go自体でIDLっぽく、インタフェースを書いて、自動生成する。“`go
package idl// 適当に構造体を宣言→componentsに入れる。
type NewPet struct {
Name string
Tag string `idl:”制約条件”`
}type Pet interface {
// (GET /pets)→pathとmethodに使う。
Find(params FindPetsParams) Pet
// -> paramsクエリの情報。Pet 200の応答。
}
“`こんな感じで、定義書いておいて、go:generateでキックして、OpenAPI spec&コード生成できるといいんかなと。
値レシーバとポインタレシーバの違いについての備忘録(new UserとUser{}を使った場合について)
Go初心者で躓いたのでメモとして残します。
`type User struct { Name string }` があるとする。
`u := new(User)`と、`u := User{}`では、値レシーバとポインタレシーバを使う際どう異なるのかを、暗黙の変換に着目してまとめてみた。“`go
package mainimport “fmt”
type User struct {
Name string
}// メソッド(値レシーバ)
func (u User) setValueName() {
u.Name = “gopher”
}// メソッド(ポインターレシーバ)
func (u *User) setPointerName() {
u.Name = “gopher”
}func main() {
// 値レシーバ
u1 := new(User) // uは*User型
(*u1).setValueName()
fmt.Println(“u1.Name:”, u1.Name, “*u1:”, *u1, “&u1”, &u1)
// u1
Raspberrypi Pi4にgo言語のインストール
# はじめに
RaspberryPi4にGo言語のインストールをする必要が出たので最新版をインストールして動作テストしてみる
なお、OSは[64biのRaspberryPi OS](http://downloads.raspberrypi.org/raspios_arm64/images/)を使用している
# インストール
以下のコマンドで、Go言語をインストールする
“`bash
wget https://golang.org/dl/go1.17.1.linux-arm64.tar.gz
tar -xzf go1.17.1.linux-arm64.tar.gz
sudo mv go /usr/local
rm -rf go1.17.1.linux-arm64.tar.gz
echo “export PATH=\$PATH:/usr/local/go/bin” >> ~/.bashrc
sourc ~/.bashrc
“`# 動作テスト
goのパスが通っていることを確認
“`bash
$ go version
go version go1.17.1 linux/
Vectyを使ってGoでフロントエンドを作ってみた話
# 注意
本記事はとりあえず動く形にしたくらいの理解度で書いた記事です。内容に誤りが含まれる可能性があります。# 概要
Goでフロントエンドを作るフレームワークである[Vecty](https://github.com/hexops/vecty)を使ってみた際の備忘録です。また、状態管理のために[Redux](https://github.com/dannypsnl/redux)を使用しています。作成したリポジトリは[こちら](https://github.com/suger-131997/todos-vecty)です。Webページは[こちら](https://suger-131997.github.io/todos-vecty/)。
[Redux Todos Example](https://github.com/reduxjs/redux/tree/master/examples/todos)を参考にしています。
# 使用したバージョンなど
– Go 1.17
– github.com/hexops/vecty
Go httpサーバー&リソースをワンバイナリにする
Go言語で 標準package のみを使用して、
httpサーバーを作成するのをやってみたいと思います。ただ httpサーバー を立てるだけだと
すぐできてしまいそうなので、今回は `go:embed` を使ってみたいと思います。## go:embed とは
httpサーバーを立てて何かページを返すようなものを作ろうと思っています。
あとリソースは、外部アクセスさせずにローカルで完結するようにします。そのためには、リソースをローカルで持たなければいけません。
例えば、画像・CSS・JavaScript などのファイルとか。。。
実行体(exe)と同じところにファイルを置いて、
exeから読み込んで返してもらってもよいのですが
ファイルを入れ忘れるとかがあると面倒なので・・・ワンバイナリにしたい!そんな時に使えるのが `go:embed` です。
リソースも実行体に含めてワンバイナリにしてくれます。Go 1.16 からリリースされたので、それ以上で使えます!
使い方もそんなに難しくないので、さっそくやってみます。
## httpサーバーを立てる
まずは、h
Go (Golang) コマンドラインツールの作り方
Golang バージョン 1.16 以上をを想定しています
環境の構築方法については次の記事を参照してください:
[Docker とVisual Studio Code を使った Go (Golang) 開発環境構築 – Qiita](https://qiita.com/y_shinoda/items/e6e2fef46408c0bae83b)## 基本
まずは Golang プロジェクトを初期化します
プロジェクト用フォルダーを作成し、そのフォルダーの直下で次のコマンドを実行します:
“`console
go mod init <リポジトリーのパス>
“`例:
“`console
go mod init github.com/yukihiko-shinoda/go-commandline-tool
“`※ リポジトリーのパスは後から変えることもできます
すると、ファイル: `go.mod` が作成されます
“`text
project/
+—go.mod
“`次に `.go` ファイルを作成します
例:“`text
project/
Go言語でAWS上、マスターデータ管理システムを実装した話
# 概要
元々、各プロダクトでマスターデータをJSON、DB、コードなどで管理していました。
PaymentMDM (Master Data Management)というプロダクトをGo言語で実装して、決済システムの共通マスタ情報の取得と運用をRestful APIを目指しています。開発しやすく、拡張しやすく、低コストでメンテできるプロダクトを作りたいと思いました。まあ、それは普通ですよね! 我々の簡単とは、後で定義します。
最初から完璧にすることを目指していませんですた。気がつく問題や開発の非効率を改善するように、継続的にベストプラクティス、またはライブラリを導入しました。そして、コードのリファクタリングを行いまいした。なんのプロダクトでも適切であるテックスタックなんて存在していないです。おそらく、テックスタックがまた変わっていくと思いますので、現状のテックスタックです。しかし、Go言語開発の他のプロダクトのニーズに一部のテックスタックが適切であることの確認ができるのではないかと思いました。例えば、PaymentMDMのテックスタックがすでに、別のプロジェクトで完全に再利用
Goでカタカナバリデーションを実装しようとしたが、unicodeパッケージのKatakanaテーブルには記号なども含まれていた。
## 現象
Goでカタカナチェックを実装する際に、
[unicodeパッケージ](https://pkg.go.dev/unicode)のKatakanaテーブルを利用していたのだが、“`Go
if !unicode.In(r, unicode.Katakana) {
return false
}
“`なんか想定外の`㋐`などの記号も通してしまうので、
Katakanaのテーブルにはどのような文字が入っているのか確認した。## 解析
unicodeパッケージのソースを見る限り、下記コードポイントの範囲で指定されている。
https://cs.opensource.google/go/go/+/master:src/unicode/tables.go;l=4709-4723
“`Go
var _Katakana = &RangeTable{
R16: []Range16{
{0x30a1, 0x30fa, 1},
{0x30fd, 0x30ff, 1},
{0x31f0, 0x31ff, 1},
{0x32d0, 0x32fe,
Goでプリミティブなアトミック操作をするならuber-go/atomicを使ってほしい話と、比較不能かつコスト0な型の話
atomicを直接使う人はそう多くないと思われるが、仮に使うようなことがあった場合は全人類標準ライブラリのsync/atomicではなく[uber-go/atomic][uber-go-atomic]を使うべきである。
## なぜsync/atomicはよくないのか
以下のようなコードにおいて、`sync/atomic`は型による保護機構が欠如しているために誤った操作に気がつくことができない。
“`go
package mainimport (
“fmt”
“sync/atomic”
)type Money struct {
price int32
}func main() {
ended := make(chan int)mine := &Money{price: 1}
go func() {
// atomic.AddInt32(&mine.price, 1) とすべきところで間違いに気が付かない
mine.price += 1
ended <- 0 }() // atomic.AddInt32(&mine.price, 1) と
Javaで飯食ってるエンジニアがGolangを学んでみる~序章~
とりあえずJavaとの差を意識してメモ書きのように書いてみる。Go→Javaの順
序章と書いたが続くかは不明。。。社会人になり、弊社に入社してからJavaを学んだのだが、
その時は学生時代に研究で利用していたFortranとの対比で基本的な文法は学んで言った記憶があった。
(やり方がいいかは別)今回もJavaとGoがいずれも静的型付け言語であることを利用し、
同じことをそれぞれの文法で書いたらどうなるかを実際にメモ書きしてみた感じ。※Editorじゃないのでミスっていたらすみませんコメントで教えてください
※全部はやってません#コンソール出力
“`Go
import “fmt”
func main(){
var human string = “TOM”
fmt.Printf(“%sは人間です”,human)
}“`
“`java
public static void main(String[] args){
String human = “TOM”;
System.out.printf(“%sは人間です”,h
Goで Chokudai SpeedRun 001 を解く
[Chokudai SpeedRun 001](https://atcoder.jp/contests/chokudai001/) を一通り解いたので、解き方やコードを載せます。
このコンテストは、私がAtCoderで過去に行われたコンテストを色々漁っているうちに見つけました。開かれた経緯が不明(有識者求む)の謎のコンテストですが、問題セットが典型問題で構成されています。そのため、私のような競プロ初心者には、典型解法の確認やライブラリの整理に使えました。問題を解く際の注意点ですが、他のコンテストと違い、共通の制約がコンテストのトップページに書かれていて、問題文に書かれていないので、合わせて読まないと罠にはまる可能性があります。最後ですが、もっといい解法があれば連絡いただけると助かります。# [A 最大値](https://atcoder.jp/contests/chokudai_S001/tasks/chokudai_S001_a)
for文を使い、入力を受け取るたびに、最大値を更新するだけ。for文を使うのが面倒でなら、$n$の上界が100しかないので、入力を全て受け取って、ソー
初心者による初心者のためのGo|製作途中だからどんどん書き加えていくよ
#Goの基礎を備忘録ってことで、綴っていきます。
初心者なので、間違ってたりしたら教えてください。##変数を宣言する
明示的に変数を定義する場合“`go
var [NAME] [TYPE]
“`暗黙的に変数を定義する場合
“`go
[NAME] := [VALUE]
“`後者に関しては、型を意識する必要がない。
#条件分岐 IF
単純にこう。“`go
if <条件式> {
<処理>
} else if <条件式> {
<処理>
} else {
<処理>
}
“`ちなみに、複数の条件式があり、ANDを使いたい場合は“`&&“`とすれば良し。
ORであれば、“`||“`でOK。##配列の長さを取得する
“`go
<長さを格納する変数> := len(<サイズを取得したい変数>)
“`##コマンドライン引数を受け取る FLAG編
まずは基本から“`go
package mainimport “flag”
import “fmt”func main() {
flag.Parse()
Go言語のechoフレームワークを使用してAPIサーバーを立てる方法(入門)
Go言語にて、echoを使用してAPIサーバーを立てる方法を解説します
## インストール
以下のコマンドでインストール“`
go get github.com/labstack/echo/v4
“`## GetのAPIを実装する
GetのAPIを実装したmain.goを作成“`main.go
package mainimport (
“net/http”“github.com/labstack/echo/v4”
“github.com/labstack/echo/v4/middleware”
)func main() {
// echoインスタンスを生成
e := echo.New()// Middleware
// httpリクエストの情報をログに表示
e.Use(middleware.Logger())
// パニックを回復し、スタックトレースを表示
e.Use(middleware.Recover())// ルーティング
e.GET(“/”, getSample)// サーバーをスタートさせる
// ポート
OpenAPI等のジェネレータツールによる更新作業の自動化、失敗時の自動ロールバックの実現
# OpenAPI等のジェネレータツールによる更新作業の自動化、失敗時の自動ロールバックの実現
こんにちは、
最近はOpenAPIやgRPCであったり、それにまつわるジェネレータツールがとても熱いですね。新規にジェネレータを走らせるのは何の憂いもなく素晴らしいのですが、
開発が進むにつれて、ディレクトリ構造が追加、変更されたり、中間処理を挟んだりと、素のジェネレータでは対応できない場合があります。
また、複数のジェネレータを使う場合、それぞれのジェネレータのご機嫌を伺わなければならない状況が発生し、そもそも更新作業にはジェネレータを使わないようになる場合も多いと思います。ジェネレートした結果が意図した結果にならなかった場合、その問題を解決するために、いちいちGit操作を行ったり、例えば、ある段階のcommitを取り消したりrebaseしたりする操作を行うとそれだけで丸1日が潰れてしまう経験をお持ちの方もいるのではないでしょうか。
今回は、ジェネレータをもっと効率的に使うために、ジェネレート作業の自動化と適切なロールバックを行うことができるスクリプトを作ってみました。
今回
Docker とVisual Studio Code を使った Go (Golang) 開発環境構築
Golang の開発環境を Docker と Visual Studio Code で約 3 分で構築する手順を解説します
Docker と Visual Studio Code を組み合わせて開発環境を準備する利点については
次の記事を参照してください:– [【Docker】【Visual Studio Code】 PC に言語をインストールせずにプログラム開発しよう | ultra code](https://futureys.tokyo/lets-develop-program-without-installing-language-by-docker-and-vscode/)
開発のためのエディターとして Visual Studio Code を利用する利点については
次の記事を参照してください:– [ファイルやプログラムの編集には Visual Studio Code を使おう | ultra code](https://futureys.tokyo/lets-use-visual-studio-code-for-editing-file-or-program/)
deferの即時評価
Go言語の勉強を始めたのですが、deferで引っかかってしまった部分があったのでまとめまてみました。
>defer ステートメントは、 defer へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで遅延させるものです。
>defer へ渡した関数の引数は、すぐに評価されますが、その関数自体は呼び出し元の関数がreturnするまで実行されません。
引用元:[A Tour of Go](https://go-tour-jp.appspot.com/flowcontrol/12)
上記の通りdeferを使うことで、呼び出している関数がreturnするまで処理の実行を遅らせることができます。
例えばファイルを閉じたりチャネルをクローズするのに使われます。
“`go:サンプルコード
func main() {
file, _ := os.Open(“./example.txt”)
defer file.Close()
data := make([]byte, 100)
file.Read(data)
fmt.Println(string(da
【Golang】mapに複数のキーを設定する
個人的に感動的に便利だったので、書いておきます。
## コード
mapのキーにstructを設定すると出来ます。
複数のキーで一つの値を持っておきたい時に便利です“`go
package mainimport (
“fmt”
)type key struct {
key1 string
key2 string
}func main() {
m := map[key]string{
key{
key1: “hoge_key1”,
key2: “hoge_key2”,
}: “hoge”,
}fmt.Println(m)
}
// 結果:map[{hoge_key1 hoge_key2}:hoge]
“`
HandleFuncとHandleでは何が起きてる?違いは?
###`HandleFunc`と`Handle`の実行部分
***注)実行したい関数、オブジェクトを`helloHandler`とする。***#### `HandleFunc`の実行部分
`http.HandleFunc(“/hello”, helloHandler)`
#### `Handle`の実行部分
`http.Handle(“/hello”, &helloHandler{})`
とても似ている!!!
なにが違うの??###`HandleFunc`と`Handle`の違い
どちらも第1引数にはURLをとる。この二つには第2引数に違いがある。
#### `HandleFunc``http.HandleFunc`は、第2引数に`http.ResponseWriter`と`*http.Request`を取る関数を**そのまま**渡せる。
#### `Handle`
`HandleFunc関数`とは違い、`Handle関数の第2引数`には関数を指定しない。`Handle`では`helloHandler型のServeHTTP関数`を定義した`Handlerのポインタ
Gomega エラーメッセージが分かりやすいEqual Matcherを作った
## 作ったもの
https://github.com/KamikazeZirou/equal-cmp
## 動機
仕事でGoのテストライブラリとしてGinkgo/Gomegaを使っているのだが、Gomegaに組み込まれているEqual Matcherは、エラーメッセージが分かりづらい。
以下のようなテストコードがあるとする。gomegaのEqual Matcherにより2つの構造体を比較し、結果が同じになるか検証している。
“`go
var _ = Describe(“Example”, func() {
It(“Example”, func() {
actual := Object{ID: 1, Name: “actual”, Tel: “Tel”, Email: “Email”}
expected := Object{ID: 1, Name: “expected”, Tel: “Tel”, Email: “Email”}
Expect(actual).Should(Equal(expected))
})
})
“`比較対象のNameの値に差異があ