- 1. 自作言語にdefer文を実装した(がGoと微妙に挙動が違う)
- 2. [Go]Collection操作が楽楽書けるsamber/loライブラリの紹介
- 3. [Go]実務でよく使うGoLandの機能
- 4. 自作Go言語WebAPIをEC2上で デーモン化する。簡単だけどつまづきやすいポイントもあった。
- 5. 【 APIキー 開発 】Go言語による自作WebAPIに原始的な APIキー 認証機能を実装する
- 6. Golangのゼロサプレス
- 7. goの -mod オプション
- 8. Dapr go-sdkのactor clientはどのようにリクエストを行っているのか
- 9. AWS SAMでGo+API Gateway+Lambda+DynamoDBのサーバレスAPI構築をIaC化した
- 10. ローカルのGoのバージョンアップはめちゃ簡単な話
- 11. 【Go】並列実行の勉強がてらスリープソートを書いてみよう
- 12. Goのmoduleのtidyに失敗した時の話
- 13. インタープリター版Go言語、gomacroを触ってみた
- 14. 【Go】middleware からハンドラ関数に値を渡すときに用いるcontext
- 15. Goの開発環境をMac上でDockerで構築する
- 16. Goで何を実装してるか
- 17. go + Echo + gormでtodo Webアプリを最速で作ってみた
- 18. ZOZOTOWNのマイクロサービス開発でバックエンドエンジニアとして学んだことをまとめます
- 19. GORMのアソシエーションの自動更新で削除した関連が復活していた
- 20. ソースコードgrep地獄を助けるSourceGraph
自作言語にdefer文を実装した(がGoと微妙に挙動が違う)
# TL; DR
– 本家(Go)は関数呼び出しのみ遅延
– 自作言語の実装では式の評価全体を遅延してしまった# はじめに
Go言語の `defer` 文を使うと、関数を抜ける際に必ず処理を実行することが可能です。
panicした場合も後処理の実行が保証され重宝しています。“`go
file, err := os.Open(“file.go”)
if err != nil {
// …
}
defer f.Close()
“`https://go.dev/ref/spec#Defer_statements
便利なので拙作の言語 [Pangaea](https://github.com/Syuparn/Pangaea) でも `defer` 文を導入しています。
(Pangaea言語自体は過去の記事でも紹介しておりますので、よろしければご覧ください)
https://qiita.com/Syuparn/items/87cafc7fd206016a0f8d
しかし、先日 「Go Quizzes 101」というGoの文法のクイズ[^quiz]を解いて
[Go]Collection操作が楽楽書けるsamber/loライブラリの紹介
元々RailsからGoの案件にうつって一ヶ月半ほど経過しました。
この間に、Rubyに存在した– 配列から条件にマッチする要素を取得する“find(detect)“
– 配列から条件にマッチする要素で絞り込んだ配列を生成する“filter(select)“
– 配列から新たな配列を生成する“map“といった**便利メソッドが標準ライブラリとして存在せずforループやら活用して自分たちでなんとかするしかない・・・というのが実情であると知って絶望** していましたが、Go 1.18で追加されたジェネリクスを利用した外部ライブラリ[samber/lo](https://github.com/samber/lo)を使えば楽に書けることを知って歓喜しました。
自分と同じように**Rails案件からGo案件に移ってきて絶望した人向けに、サンプルコードで対比して紹介**したいと思います。
また、このライブラリには弱点も存在するので、その辺も交えて紹介したいと思います。なお、Rubyでは配列は「Array」と呼び、Goでも配列はあるけど、実際使うのはほぼ動的配列である「Sli
[Go]実務でよく使うGoLandの機能
Goの現場に入り、コーディングに使用するエディタが VSCode から **GoLand**(こっちはIDEですが)になって一ヶ月半ほど経過した。
諸先輩方にアドバイスをいただいた上で、自分が取り入れたプラグインや機能が頭打ちになったのでアウトプットしておく。
GoLandは日本語化してる前提。また、ショートカットはMac前提。# 1. プラグイン
プラグイン名|説明
—|—
Indent Rainbow|インデントを階層ごとに色分け
Rainbow Bracket|カッコを階層ごとに色分け
GitToolBox|エディタ内各コードのコミット履歴を表示するVSCodeでお世話になっていた一部の拡張機能の代替品。
# 2. 機能
## 2.1. 検索・置換機能|操作
—|—
ファイル検索|Command + Shift + O (後述のShift2回からでも可能)
ファイル(アクティブな)内の文字列検索 or 置換|Command + F or R
複数ファイル内の文字列検索 or 置換|Command + Shift + F or R
複数ファイ
自作Go言語WebAPIをEC2上で デーモン化する。簡単だけどつまづきやすいポイントもあった。
今回はGo言語で作成した自作のお問い合わせメールAPIを、EC2からログアウトした後でも デーモン によってmain.goが実行され続けるようにします。つまりパソコンを閉じてもgo run main.goの処理が止まらないようにします。
前回、EC2環境で実行させることでAPIがインターネットにつながり、ようやくWebAPIが実用的なものになったと思われました。
しかし実際やってみると、EC2でコマンド「go run main.go」によってAPIは動作したのですが、EC2をログアウトすると実行も途切れてしまいました。これでは実用的とは言えません。
## デーモン とは
そこで必要になるのがデーモンです。
デーモンという名前ですが、怖いものではありません。
デーモンとは、バックグラウンドで実行処理をしてくれるおかげで、パソコンを閉じてもEC2のインスタンスが実行状態である限り実行ファイルの実行が途切れなくなるプログラムです。
そしてデーモン状態に切り替えることをデーモン化と言います。
EC2環境でAPIが動作することが前提です。EC2での動作方法はこちらの記事をご覧くだ
【 APIキー 開発 】Go言語による自作WebAPIに原始的な APIキー 認証機能を実装する
今回は自作のWebAPIに APIキー 認証機能を実装します。様々なツールやライブラリもありますが、今回はそのようなものは使わず、最低限の認証機能をプログラミングだけで作成します。Web通信に0からAPIキー認証機能を実装したいという方の参考になれれば幸いです。
## 土台となるAPI
今回APIキーを実装させるAPIは、前に作ったGo言語・RESTAPI・SendGridによるお問い合わせメールAPIです。作り方や使用は[こちら](https://qiita.com/haruki-lo-shelon/items/3ed239d5479f84b10384)の記事から参照できます。(少しプログラムに変更点もあります。詳しいコードは[GitHub](https://github.com/haruki-lo-shelon/go_sendEmail2)に掲載)
https://qiita.com/haruki-lo-shelon/items/3ed239d5479f84b10384
https://github.com/haruki-lo-shelon/go_sendEmail2
#
Golangのゼロサプレス
## ゼロサプレスとは
例えば`“000012″`という文字列があったときに、頭についている余計な`”0”`を取り除くこと
“`
// ゼロサプレスの例
000012 → 12
001234 → 1234
000101 → 101
000110 → 110
“`### 最初にゼロサプレスをするために考えたこと
文字列を一つ一つ見ていって、0ではないものが出てきた時に別スライスにappendすればいいんじゃないか
“`go: before.go
package mainimport (
“fmt”
“strings”
)func zeroSuppress(str string) string {
slice := strings.Split(str, “”)
res := make([]string, 0)
flag := falsefor _, v := range slice {
if v != “0” {
flag = true // 0でないものが現れたら、flagをtrueにしてappendするようにした
}
if
goの -mod オプション
* [Build Command – Go Modules Reference – The Go Programming Language](https://go.dev/ref/mod#build-commands)
パッケージ情報を必要とする go の一部のコマンド実行時に `-mod` オプションを指定することができる。
`vendor` `mod` `readonly` のいずれかの値を指定可能。対象となるコマンドの例として、`go build` `go run` `go test` などがある。
# 指定できるオプション
## `-mod=vendor`
モジュールの参照先として `./vendor` ディレクトリ配下を使用するする。ネットワーク経由でのダウンロードやモジュールキャッシュの使用はしなくなる。
`./vendor` ディレクトリは `go mod vendor` コマンドで生成することができる。## `-mod=mod`
`./vendor` ディレクトリが存在する場合でもモジュールの参照先として無視する。
また現時点のソースを見て、`imp
Dapr go-sdkのactor clientはどのようにリクエストを行っているのか
# TL; DR
– go-sdkのactor client作成時にgRPCリクエスト実装は不要
– ユーザーが指定するのは関数フィールドの定義のみ
– `client.ImplActorClientStub` が `reflect` を使って動的に関数生成# はじめに
Daprのactorを使ってみようとgo-sdkのサンプル実装を見ていたところ、クライアント側にgRPCリクエスト処理が見当たりませんでした。
https://github.com/dapr/go-sdk/blob/b465b1fa07211ee8a43bdd66906423d2e9e14ebd/examples/actor/api/actor.go
“`go:examples/actor/client/main.go
// actorのメソッドGetUserを呼び出し。この実装はどこにある?
user, err := myActor.GetUser(ctx, &api.User{
Name: “abc”,
Age: 123,
})
“`メソッドを追いかけようとするも、実態はフィールドで定義が
AWS SAMでGo+API Gateway+Lambda+DynamoDBのサーバレスAPI構築をIaC化した
# はじめに
前回Goで作成したAPIの環境構築をSAMでIaC化しました。https://qiita.com/tkhs1121/items/7b193dcce19539f16761
# 環境
MacBook Air M1
開発言語 Go# 手順
AWS CLIとSAM CLIをインストールします。
“`shell
brew install awscli
brew tap aws/tap
brew install aws-sam-cli
“`AWSコンソールのIAMからアクセスキーを作成して、クレデンシャルを設定します。
“`shell
aws configure
“`前回のソースディレクトリにSAMの`template.yaml`を追加します。
https://github.com/tkhs1121/go-serverless-app-3
## ソースコード
“`yaml:template.yaml
AWSTemplateFormatVersion: ‘2010-09-09’
Transform: AWS::Serverless-2016-10-
ローカルのGoのバージョンアップはめちゃ簡単な話
# 前提
Macでしか試していません。
古いバージョンのGoは、Go公式からダウンロードしてインストールした場合。# バージョンアップ方法
[Goの公式サイト](https://go.dev/doc/install)でDownloadボタンを押して、インストールを進めるだけです。既にGoがインストール済みの場合は以下のポップアップがでます。OKを押すだけで古いバージョンを削除したうえで、新しいバージョンをインストールしてくれます。
![Goのインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221948/040cb241-bcc1-ebf5-531d-d2d786461f27.png)自分で古いGoをアンインストールする手間もないので、めちゃ楽ですね!
【Go】並列実行の勉強がてらスリープソートを書いてみよう
# まえがき
ゴルーチン、まるで分らない…Fuseです
そんな悩みを解決しようと並列実行が使えそうなものを考えてはみたもののなかなか思いつかない、
そんな中、Wikipediaを漁っていたら…
>バケットソートのバケツをメモリ空間の代わりに時間に置き換えたもので、もともと掲示板4chanに投稿されたアイデアである。
>「全要素の最大値×スリープさせる単位時間」で実際にソートできてしまう。それが役に立つ事例は例題程度であろう。[バケットソート/スリープソート](https://ja.m.wikipedia.org/wiki/%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%82%BD%E3%83%BC%E3%83%88#.E3.82.B9.E3.83.AA.E3.83.BC.E3.83.97.E3.82.BD.E3.83.BC.E3.83.88)より引用
### これだッ!!
というわけで作ってみました。
## 完成品
## ソースコード
https://github.co
Goのmoduleのtidyに失敗した時の話
`go mod tidy` をローカルで実行してモジュールのお掃除をしようとしたところ、以下のエラーになりました。
“`
% go mod tidy
go: go.mod file indicates go 1.19, but maximum version supported by tidy is 1.18
“`英語弱者の私は、「 `go mod tidy` は廃止されたのかー。この間できたばかりの機能だったのになー。」などと勘違いしてしまいした。
違います。
原因は `go.mod` に記載のGoのバージョンよりもローカルのGoのバージョンが古いだけでした。
ローカルのGoのバージョンを1.19にしてエラーがでなくなりました!記事にするほどの内容でもないですが、念の為、備忘録として残しておきます。
インタープリター版Go言語、gomacroを触ってみた
# はじめに
Go言語のインタープリターを探していたところ、gomacroという処理系を見つけました。
https://github.com/cosmos72/gomacro
独自機能も多く、処理系を超えて「Go言語の方言」になっていると感じたので、本記事ではgomacroの機能について紹介したいと思います[^intro]。
以下は記事執筆時点でのmasterブランチを使用しています。
# REPL
PythonやRuby等のような、対話的にコードを実行できるモードがあります。1行おきに式がそのまま評価されます。
“`
// Welcome to gomacro. Type :help for help, :copy for copyright and license.
// This is free software with ABSOLUTELY NO WARRANTY.
gomacro> 6 * 7
{int 42} // untyped.Lit
“`もちろんprintも可能です。ちゃんと戻り値も全て表示されます。
“`
gomacro>
【Go】middleware からハンドラ関数に値を渡すときに用いるcontext
# はじめに
Goで middleware からハンドラ関数に値を渡したい場合,contextを使って以下のように書くことが多いと思います.
“`go:middleware内
import (
“context”
“net/http”
)func exampleMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), “hoge”, hoge)
next.ServeHTTP(w, r.WithContext(ctx))
}
}
“`“`go:ハンドラ関数
func exampleHandlerFunc(w http.ResponseWriter, r *http.Request) {
v := (r.Context()).Value(“hoge”)
hoge, ok
Goの開発環境をMac上でDockerで構築する
#### 今回の目的
今回はGoの開発環境をM1 Macbook pro上にRancher desktopを利用してコンテナ環境を構築します。そこで[Tour of Go](https://go-tour-jp.appspot.com/list)の環境を実行します。
オンラインでもできますが、せっかくなので写経的な形で進めるためにGoの環境を用意します。多少環境祭などもでてくるでしょうが細かいことは気にせずにやっていきます。
kubernetesとかを仕事で使っているのですが、Goで作成されている製品なのでGo言語自体の学習もしたいなと思った次第です。#### 環境
“`
M1 Macbook pro: macOS Ventura 13.0.1
Rancher desktop v1.7.0
コンテナイメージ: Ubuntu20.04
Go: v1.19.4
“`Rancher desktopはDocker desktopと同じような製品ですが、CRIにdockerとcontainerd選ぶのを選べたりkubernetesのバージョンアップ検証ができたりと便利な製品となっ
Goで何を実装してるか
## 概要
現在自分が開発しているプロダクトでは、メインの言語にGoを採用している
なぜGoを選定して、Goで何を開発しているかを書く## API
他の言語でも問題ない部分ではあるが、GoでAPIを書く上で特に困っている点はない
フレームワークにGinを採用したが、標準パッケージだけでも問題なく実装できるhttps://gin-gonic.com/
Swaggerドキュメントが生成できて、Swagger UIも使えるのでswagは便利
https://github.com/swaggo/swag
## CLI
Cobraがめちゃくちゃ便利
クロスコンパイルもできるので、今のところGoがCLIを作るのに一番快適https://cobra.dev/
## Kubernetesのカスタムコントローラー
これがGoを選定した最も大きい要素
Kubernetesのカスタムコントローラーを実装するなら基本的にはGoを選定することになると思う
フレームワークとしてkubebuilderを使用しているhttps://book.kubebuilder.io/
go + Echo + gormでtodo Webアプリを最速で作ってみた
# go + Echo + gormでtodo Webアプリを最速で作ってみた
go + ginを使いまわしてEchoでTodoアプリを作ってみました。
環境:Macbook + Goland
#機能概要
* todoリスト
* todo作成
* todo更新
* todo削除# Echoのインストール
[Echoの公式サイト](https://echo.labstack.com/)“`go get github.com/labstack/echo/v4“`
## その他ライブラリのインストール
### GORM:O/Rマッパー
[gormの公式サイト](https://gorm.io/ja_JP/)
* gormのインストール
“`go get -u gorm.io/gorm“`
* gorm sqliteドライバのインストール
“`go get -u gorm.io/driver/sqlite“`### configライブラリのインストール
“`go get gopkg.in/ini.v1“`### todoアプリの開発
#### ディレクト
ZOZOTOWNのマイクロサービス開発でバックエンドエンジニアとして学んだことをまとめます
# はじめに
ZOZOTOWNのシステムリプレイスプロジェクトにおいて、API GatewayやID基盤、会員基盤のマイクロサービス開発をバックエンドエンジニアとして2020年から約2年経験しました。その経験の中で私が技術的に学んだTipsをまとめます。なお、開発言語はGoですがGoに限らない内容も含まれます。# Go言語が関連すること
## エラー系
### wrap
Go1.13以降、errorsパッケージでエラーのwrapができるようになりました。wrapすることで元のエラーを保持したまま返すことができます。%w記法でエラーをwrapします。“`go
return xerrors.Errorf(“%w”, ErrMemberNotExists)
“`wrapの使いどきですが、エラーをハンドリングする箇所で、元のエラーに対してerrors.Isやerrors.Asメソッドを実行する場合はwrapします。それ以外ではwrapする必要がないため、代わりに%vを使います。
### xerrors
xerrorsを使うとエラー発生箇所の追跡がしやすくなります。具体的には
GORMのアソシエーションの自動更新で削除した関連が復活していた
# 起きたこと
GORM(v1.9.16)を使っていて、アソシエーションの削除がうまくいかなかったときにハマったのでその時の調査メモです。
Productモデルと、そこに紐づくShopモデルを並行して更新するようなプログラムを作成していました。“`go:main.go
package mainimport (
“github.com/my-best/products.my-best.com/go/internal/models”
“golang.org/x/sync/errgroup”
)func main() error {
var product models.Product
eg := errgroup.Group{}
eg.Go(func() error { return updateProduct(&product) })
eg.Go(func() error { return updateProductShop(&product})
// 略
}
“``updateProductShop`の内部では不要になっ
ソースコードgrep地獄を助けるSourceGraph
# はじめに
コードを書いている時間と比較して、コードを「理解している」時間はどれくらいかかるのでしょうか?
[Software社が自社サービスのユーザ約25万人から集計した結果](https://www.software.com/reports/code-time-report)からは、以下のようになっていました。
* **コードを書いている時間:56%** (1日あたり平均52分)
* **コードを「理解している」時間:44%** (1日あたり平均41分)コードを「理解している」時間はコードを書いている時間に匹敵するほどになっていることがわかります。
このコードを「理解している」時間は、具体的には次のようなものがあります。
* コードを表示して「読んでいる」時間
* プルリクのレビューをしている時間
* コードの理解のためにドキュメントを読んでいる時間今回は上記のうち**コードを表示して「読んでいる」時間**を効率化できないか考えてみます。
# コードを「読んでいる」時間について
コードを「読んでいる」時間のよくあるケースとして、コード変更前の下調べ作業があります。
以降