- 1. Goのモックライブラリを比較検討する
- 2. 初めてGo言語をやってみて分かったこと。
- 3. Goのネットワークプログラミングでよくあるエラーのbroken pipeを深く理解するために
- 4. CloudBuildでgolangci-lintを実行する
- 5. entでeager_loadingを実装する
- 6. C# -> Golang
- 7. コンパイル型言語とは
- 8. ユニクロのTシャツのコードを実行しようとしたら意図せずGO言語に入門した
- 9. WSL2にインストールしたtinygoでtinygo monitorをraspberry pi picoで実行
- 10. 【個人開発】趣味で作ったWebアプリをNext.js使ってリプレイスしたらページパフォーマンスが90くらいになった話
- 11. goでweb漫画のサイトをスクレイピングしてRSSを作成する
- 12. filepath.WalkDirでディレクトリ内を削除するときには注意
- 13. GOジェネレータとクロージャについて基本
- 14. Go | errgroup.Group に至るまで
- 15. GoでgRPC API超入門
- 16. GoとRedisで作る簡単従業員管理アプリ
- 17. Go | 同じ名前の関数で引数の数を変える
- 18. Go | Strategy + Null Object
- 19. Go | Union を Interface で実現する
- 20. [備忘録] Go CloudFunctionsでChain Middlewareを利用する
Goのモックライブラリを比較検討する
# 概要
Goのモックライブラリはいくつか存在しており、検討を始めるにあたって [Comparison of golang mocking libraries](https://gist.github.com/maratori/8772fe158ff705ca543a0620863977c2#user-content-fn-12-14e5dadb9d5bbfc4c34632f365c8a95b)の内容が大変参考になった。このうち候補として考えた gomock, mockery, moq をそれぞれ使ってテストコードを書いてみた所感を元に、比較検討した結果をまとめる。
# はじめに:なぜモックライブラリが必要なのか
Goのテストコードで依存するインターフェースをモックする時、モックライブラリを使わずとも自前でモックを実装することは可能である。
例えば、以下のような `GetUserService.Get()` のテストコードを考えてみる。“`go
type UserRepository interface {
GetUser(userId string) (User, er
初めてGo言語をやってみて分かったこと。
# C言語と最近のモダンな言語(Java、C#、Pythonなど)のいいとこ取りをした感じ
* C言語的要素
基本的にGo言語はコンパイラ言語であり、ビルドを実行すると機械語に変換されるのですが、
機械語は直接CPUに命令を出す形式なので、めちゃくちゃ動作スピードが早いです。
コンパイラ言語はGo言語以外に、C言語、C++、Rust等があります。また、Go言語はクラスという概念は存在しないので(似たようなパッケージという概念はありますが)、
その点も同じと言えます。* Java的要素
モダンな言語だと、C言語には無かったListのような、要素を自由に追加削除できるるような仕組みがあります。
最近の言語だから、こういった仕組みなども扱えるようになっています。また、例外処理(try-catch)のような仕組み(panic-recover)も用意されています。
* Python的要素
Pythonのようなスクリプト言語はソースファイルをあれこれ変換しなくてもすぐに実行できるのが特徴ですが、Go言語もいちいちビルドする必要は無く、ソースコードの状態のままで実行できるオプシ
Goのネットワークプログラミングでよくあるエラーのbroken pipeを深く理解するために
Goでネットワークアプリケーションを開発する際、時々「broken pipe」というエラーに遭遇することがあるでしょう。この記事では、このエラーの意味を説明して、再現するためのコードを示して、基本的な対処法をいくつか紹介します。
「broken pipe」は通常、**(通信している同士の一方が)相手がリセットした(RST)TCPコネクション**にデータを書き込もうとしたときに発生する。このエラーは以下のコードで再現できる。
“`go
// …
var done = make(chan struct{})func server() {
listener, err := net.Listen(“tcp”, “:8080”)
if err != nil {
log.Fatal(err)
}
defer listener.Close()done <- struct{}{} conn, err := listener.Accept() if err != nil { log.Fatal("S
CloudBuildでgolangci-lintを実行する
## 結論
`cloudbuild.yaml`に以下を追加すれば、実装できます“`yml: cloudbuild.yaml
steps:
# golangci-lintのDockerイメージを指定する
– name: ‘golangci/golangci-lint’
# デフォルトの設定でgolangci-lintを実行する
args: [‘golangci-lint’, ‘run’]
“`## golangci-lint[^1]とは
[^1]: https://github.com/golangci/golangci-lint> `golangci-lint` is a fast Go linters runner.
>It runs linters in parallel, uses caching, supports YAML configuration, integrates with all major IDEs, and includes over a hundred linters.`golangci-lint`は高速なGoリン
entでeager_loadingを実装する
# 書くこと
– GolangのORMであるentでEager Loadingを実現する方法
– INNER JOIN、LEFT JOINなど
– 他テーブルのWHERE、ORDERなど
– 他テーブルのデータの取得はPreloadになってしまう# 書かないこと
– テーブルの定義方法
– schemaの書き方# なぜ記事を書いたか
– INNER JOINやLEFT JOINの方法が書かれている記事や公式が少なく、自分で色々試して知見が深まったため# 参考文献
https://entgo.io/ja/docs/predicates/# JOINの行い方
## ER図
“`mermaid
erDiagram
organizations ||–o{ users : has
organizations {
int id
string name
}
users {
int id
string name
int organization_id
}
“`## Source
“`golang
import (
ent
C# -> Golang
# 目次
# まえがき
C#使いがGo言語に移行するときに役立ててほしいと思い書きました。C#についての詳しい説明は割愛します。
# 言語概要
– Google が開発したプログラミング言語です。「**Go言語**」や「**Golang**」と表記されます。
– UNIX、B言語(C言語の元)、UTF-8の開発者ケン・トンプソンや、UNIX、Plan 9、UTF-8の開発者ロブ・パイクによって設計されました。
– 静的型付け、メモリ安全性、ガベージコレクションを備えるコンパイル言語です。
– シンプル、高速、メモリ効率が良い、メモリ破壊が無い、並行処理が得意などの特徴を備えています。
– メモリ破壊が無く、並行処理を得意とする、進化したC言語という側面があります。
– Linux、Mac OS X、Windows、Android、iOS で動作します。# 言語仕様
### セミコロン
C系統の言語と違い、基本的にセミコロンは必要ない
“`csharp
int hoge = 123;
int fuga = 456;
“`“`go
// セミコロンは各行に書く
コンパイル型言語とは
# コンパイル型言語とは
人間が書いたソースコードを、コンピュータが分かるように機械語に変換(コンパイル)してからプログラムを実行する言語のこと。インタプリタ型言語とは違い、一度にすべてのソースコードを変換してから実行する。
(インタプリタ型言語は、ソースコードを一行ずつ実行してプログラムを実行する言語である)### コンパイル型言語の例
Java, C#, Go### インタプリタ型言語の例
JavaScript, Python, Ruby, PHPなど
ユニクロのTシャツのコードを実行しようとしたら意図せずGO言語に入門した
# はじめに
ユニクロのバラエティゾーンで売ってるプログラムが書かれたTシャツありますよね。
そもそもGOで書かれているとすら知らなかったのですが、GOについて何も知らない状態から動かしてみました。
筆者は普段C#とPHPをメインに使用していて、GOは全くの素人です。
意図せずGOのHelloWorldみたいになったので記事にします。—
とりあえず実行してみたい方は以下のレポジトリで実行できます。
Dockerが入っていればGOが入ってなくても動きます。https://github.com/Pokeyama/uniqlo-tshirt-app
# シャツとコード
iPhoneで撮ると勝手にOCRして文字として読み取ってくれたので、そのままGPTに整形してもらっ
WSL2にインストールしたtinygoでtinygo monitorをraspberry pi picoで実行
# WSL2にインストールしたtinygoでtinygo monitorを実行
どうしてもWSL2でtinygoを動かして、
rapberry pi pico相手に `tinygo monitor`を実行したかった。備忘録としてメモをまとめる。
## 実行環境
– Windows 11
– WSL2 Ubuntu 22.04LTS
– golang 1.22.5
– tinygo 0.32.0## 手順
### 1. golang, tinygoをインストール
### 2. ソースコードを作成
今回は下記 `sample.go`“`golang
package mainimport “time”
func main() {
for {
println(“hello world!”)
time.Sleep(time.Second)
}
}
“`### 3.モジュール解決
`go mod init sample`
`go mod tidy`### 4. コンパイル
`tinygo build -target=pico -o ./sample.
【個人開発】趣味で作ったWebアプリをNext.js使ってリプレイスしたらページパフォーマンスが90くらいになった話
はじめまして!もんたです。
ちょこっと前に[もんたの森っていう個人開発のWEBアプリケーションをリリースした話](https://qiita.com/Maminumemonta0706/items/9e8632698fb6a8329b8c)をしたんですが、この記事では『そのもんたの森のリプレイス企画を実施したよ〜』って話をしようかと思います。
この記事を読んで僕と同じかけだしエンジニアの個人開発のモチベーションにつながれば幸いです!
あ、そういえばいろいろやらせてもろてます。
よかったら覗いてみてあげてください。**【たまーに描いた絵をアップする X ( Twitter ) 】**
https://x.com/monta_no_mori
**【最近始めた Instagram 】**
https://www.instagram.com/monta_no_mori/
**【もんたのLINEスタンプ】**
https://store.line.me/stickershop/author/2887587/ja
## 今回作ったやつ
https://www.montano
goでweb漫画のサイトをスクレイピングしてRSSを作成する
# 前説
– もともと PHPで自分の読んでいるweb漫画のサイトをスクレイピングしてRSSを作成するツールを作っていた
– https://github.com/background-color/webcomic-crawler
– 10年近く経ち、ライブラリも古くなってしまっていたので、Goで作り直すことにしました# 仕様
– 巡回するURL,読み込むセレクタはDB保持する
– DBからURLを取得し、セレクタの情報を取得する
– 取得した情報は、前回取得した情報と異なればDBに保持する
– 同じ場合は保持しない
– 取得した最新情報はRSSファイルに出力
– RSSリーダーで読み込みたいため# 開発
## スクレイピングライブラリ
### 要件
– クライアントサイドレンダリングのページも読み込めること
– セレクタを指定して要素が取得できること
– 現行の仕様をそのまま使いまわしたいというわけで、 [go-rod/rod](https://github.com/go-rod/rod) を使うことに
### コードを書いて動作確認`
filepath.WalkDirでディレクトリ内を削除するときには注意
# やりたいこと
処理が終わった一時ディレクトリ内を綺麗したい。
でも、親ディレクトリは残しておきたい。
ディレクトリ内は階層が統一されていない。## 削除したいディレクトリ構造
“`
.
├── parentDir1
│ ├── ChildDirA
│ │ └── ChildDirAA
│ └── ChildDirB
└── parentDir2
“`## 試したこと
2つの方法で実施
* ReadDir
* filepath.WalkDir
filepath.WalkDirのほうが処理速度が早いという記事情報あり。## ReadDirでディレクトリ内を取得
“`go
package mainimport (
“fmt”
“io/ioutil”
“os”
“path/filepath”
)func main() {
dir := “your_directory_path” // 対象のディレクトリパスをここに指定err := removeSubdirectories(dir)
if err != nil {
fmt.
GOジェネレータとクロージャについて基本
## ジェネレータ
ジェネレータとは、遅延評価によって値を生成する関数やメソッドのことを指す。ジェネレータは通常、データのシーケンスを逐次的に生成するために使用される。ジェネレータの実装
GoにはPythonやJavaScriptのような組み込みのジェネレータ機能はないが、チャネルとゴルーチンを使ってジェネレータのような機能を実装することができる。“`go
package mainimport “fmt”
// ジェネレータ関数
func fibonacci() chan int {
ch := make(chan int)
go func() {
x, y := 0, 1
for {
ch <- x x, y = y, x+y } }() return ch } func main() { fib := fibonacci() for i := 0; i < 10; i++ { fmt.Println(<-f
Go | errgroup.Group に至るまで
雑めも
– `errgroup.Group` を使っているけど、より原理的に書くとどうなるか整理
– 逆にいうと原理的に書くスタイルから、どうブラッシュアップされていくかみてみる## `sync.WaitGroup`
– [Playgound](https://goplay.tools/snippet/BkUvjnk4s2S)
– 実行完了の制御として `sync.WaitGroup` を使う“`go
package mainimport (
“fmt”
“sync”
)func main() {
var wg sync.WaitGroup // 実行完了の制御用for i := range 5 { // 非同期N回実行
wg.Add(1) // increment
go func() {
defer wg.Done() // decrement
fmt.Printf(“i is %s\n”, i)
}()
}wg.Wait() // wait
}
“`## `sync.WaitGroup` + `chan` を使っ
GoでgRPC API超入門
自分の中で少しずつ理解できてきたので、小分けにして整理していきたくこの記事を書きました。
同じ初学者のお役に立てれば。::: note
当記事は実装メインで解説します。
protoって何の略?これは内部でどうなってるの?的な細かい話は省いています。
気になるところがあったら他記事で補完してください🙏
:::## 構成
今回は最小限の超簡単な構成とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/f317ee38-fcdc-4807-dd65-089a1af1f128.png)
初学者はHello,World!を出力しなければならないという法律に則り、Hello,World!を出力するAPIを実装していきます。実装では、クライアントのインスタンス、gRPCサーバのインスタンスをそれぞれ立ち上げ、リクエスト〜レスポンスまでの流れを確認する、ということをやります。
## 大まかな手順
ゆるふわ概念図を記しておきます。
### 全体像
まずは作成するものの全体
GoとRedisで作る簡単従業員管理アプリ
# GoとRedisの勉強のために作りました
こんにちは!今回は、Go言語とRedisを使って、シンプルだけど便利な従業員管理アプリを作っていきます。プログラミング初心者の方も、ベテランの方も、一緒に楽しく学んでいきましょう!
## 1. 環境設定
まずは開発環境を整えましょう。GoとRedisをインストールして、必要なパッケージも用意します。
“`go
go mod init employee-app
go get github.com/go-redis/redis/v8
“`これで準備オッケーです!さぁ、コーディングを始めましょう。
## 2. Redisクライアントの設定
次に、Redisに接続するためのクライアントを設定します。
“`go
package mainimport (
“context”
“github.com/go-redis/redis/v8”
)var ctx = context.Background()
func newRedisClient() *redis.Client {
return redi
Go | 同じ名前の関数で引数の数を変える
雑めも
– https://xuri.me/excelize/en/sheet.html#SearchSheet を使ってて
`f.SearchSheet(sheet, kw, true)`
と
`f.SearchSheet(sheet, kw)`が許容されてるのに気づいたのでメモ
## 末尾に1つ要素の有無をコントロールする
– [Playground](https://goplay.tools/snippet/qLiuZ23dLjM)
“`go
package mainimport (
“fmt”
)func main() {
// opt arg なし
fmt.Println(“>> no opt arg”)
f1(“:D”)
fmt.Println()// false
fmt.Println(“>> false”)
f1(“:D”, false)
fmt.Println()// true
fmt.Println(“>> true”)
f1(“:D”, true)
fmt.Println()// invalid
Go | Strategy + Null Object
## 雑めも
– ストラテジーパターン
– アルゴリズム(ストラテジー)を注入して使う。Excelストラテジー、PDFストラテジー、Nilストラテジーのどれか。
– それぞれのストラテジーごとに、構造体が違うため保持できるデータも異なる(`Excel.excel` と `Pdf.pdf` の箇所)– Null Object
– Nilストラテジーは Null Objectパターンで、`nil` ではなくて処理をしない構造体を渡しておくと実行時に nil チェックが必要なくなる– インジェクション
– ストラテジーを注入するタイミングがコンストラクタによる生成時かメソッドを実行時によってやり方が異なる## ストラテジーパターン(コンストラクタインジェクション)
– [Playground](https://goplay.tools/snippet/pKsizrTUHne)
“`golang
package mainimport “fmt”
func main() {
var ct Content// Excel
ct = Content{
Go | Union を Interface で実現する
最近はもっぱらGoを書いてるがメンタルモデルがTypeScriptに引きづられていたのでコード例を交えて比較して書いてみる。
## Go
– [Playground](https://goplay.tools/snippet/7G3Ao59_hfP)
– Interfaceで実現する
– identifyなどのようにAやBごとのそれぞれの処理は、それぞれの構造体に対してメソッドを生やす形で実現する
– ダックタイピングなので、AとBはInterfaceのAorBのことを知らない。`AorB` のInterfaceを満たすものならA、B以外でも入れられる“`go
package mainimport (
“fmt”
)func main() {
{
// A
c := ContainerItem{AorB: A{IamA: “なんかの値A”}}
c.Echo(“A: “)
}{
// B
c := ContainerItem{AorB: B{IamB: 123}}
c.Echo(“B: “)
}{
// Inte
[備忘録] Go CloudFunctionsでChain Middlewareを利用する
# Go CloudFunctionsでChain Middlewareを利用する
経緯
フト思った時に変態っぽいコードの書き方をしていたので、備忘録。
###### TL;DR
呼び出し元のfunctionsで、http.HandlerFunc(handler).ServeHttp(w, r)で実施する。
“`middleware.go
package middlewareimport “net/http”
type Middleware func(http.Handler) http.Handler
func ChainMiddleware(h http.Handler, m …Middleware) http.Handler {
if len(m) < 1 { return h } wrapped := h for i := len(m) - 1; i >= 0; i– {
wrapped = m[i](wrapped)
}return wrapped
}func LoggerMiddleware(next http.Ha