Go関連のことを調べてみた

Go関連のことを調べてみた

クリーンアーキテクチャに入門してみた 後編

# はじめに

– 前回クリーンアーキテクチャの理論的な部分を学んだので今回は実際にクリーンアーキテクチャで簡単なサンプルアプリの実装をしてみたのでその解説です
– [前回の記事](https://qiita.com/aaaasahi_17/items/b4b4d08dbad45a270bd8)
– 実装にはGo言語を使用しています

# 実装

## 構成など

### 実装したサンプルアプリのリポジトリ

https://github.com/aaaasahi/go-clean-app

### 使用技術

– Go 1.21.0
– echo (https://github.com/labstack/echo)
– MySQL 8.0

### ディレクトリ構成

“`
├── application # ユースケース
├── config # 各種設定値
├── domain   # ビジネスロジックのコア部分(エンティティ、リポジトリインターフェース)
├── infra   # データベースなど外部サービスとの通信
├──

元記事を表示

gRPCのバリデーションツール「protovalidate」を使ってみよう

# protovalidate とは?

protovalidate は、Buf が提供する gRPC のバリデーションツールです。Protobuf Validation の後継にあたり、proto ファイル内でバリデーションルールを定義することができます。

# protovalidate の主な特徴

– protoファイル内でデータのルールを直接定義できる
– 文字列の長さ、正規表現、値の範囲など、さまざまなルールを設定可能
– PGV(protoc-gen-validate)よりも高速で軽量
– PGVよりも処理が速く、メモリの使用量が少ない
– Go言語をはじめ、様々な言語に対応
– Goだけでなく、他の言語でも利用可能

# 使い方

## 1. buf のインストール

protovalidate を使うには、まず buf をインストールする必要があります。[公式サイト](https://buf.build/docs/installation/)からインストーラをダウンロードしてください。

## 2. proto ファイルの準備

proto ファイルに p

元記事を表示

GitHub ActionsでGolangとProtocol Buffersのコード品質を維持しよう!

# はじめに

ソフトウェア開発においてコード品質を維持することは非常に重要です。コードの品質が低下すると、バグの発生リスクが高まり、保守性や拡張性が損なわれてしまいます。そこで、コードの品質を自動的にチェックするためのツールを導入し、CI/CD パイプラインに組み込むことが有効な対策となります。

この記事では、GitHub Actions のワークフローファイルを使って、Golang のコードとスキーマファイル(Protocol Buffers)の品質をチェックする方法を紹介します。

# ワークフローファイルの概要

以下のワークフローファイルは、2 つのジョブから構成されています。

“`yml
name: Lint for Golang

on:
push:
pull_request:

jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v4
– uses: golangci/golangci-lint-action@v6

元記事を表示

Go言語の特徴

# はじめに
ソフトウェア開発の世界には、多くのプログラミング言語があります。
Python、JavaScript、C、Ruby、最近ではRustやKotlinなど、それぞれ特徴があります。
様々なプログラミング言語に触れてきました。その中でも私が特に印象に残っているGo言語について解説したいと思います。
# Go言語とは
“**Go**”という名前にもあるようにGoogleが開発した言語です。
2009年に発表され、現在では様々なサービスに利用されています。
日本のサービスだと、メルカリやクックパッドなどがあります。[^1]
![スクリーンショット 2024-06-06 160725.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/2075dcef-9ad5-e3ed-9f04-dfe5fde9b159.png)
# 特徴
特徴は大きく分けて3つほどあります。後ほど順に解説します。
* コンパイラ型
* 記述がシンプル
* 未使用の変数、モジュールはエラーになる

## コンパイラ型

元記事を表示

【Go言語】パニック

# はじめに

Goにはtry/catchがないが、panicやrecoverをむやみにつかってはいけない。一般的には、error型で返すのが好ましい。

# panicとは

[Go Playground](https://go.dev/play/p/AQKptHYU6SO)

“`go
func main() {
fmt.Println(“a”)
panic(“foo”)
fmt.Println(“b”)
}
“`

パニックが発生すると、現在の goroutine がリターンするか、recover でパニックが捕捉されるまで、パニックはコールスタックをさかのぼる。

以下はrecoverで捕捉する例である。

“`go
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println(“recover”, r)
}
}()

f() // パニックが発生するfをコールする
}

func f() {
fmt.Println(“a”)
panic(“foo”)
fmt.

元記事を表示

AWS Lambdaを定期的に実行するためにEventBridgeを設定する [Terraformを使用]

## 要約
最終的なソースコード全体は以下のリンクからご確認いただけます。

https://github.com/mochi-yu/qiita-material/tree/main/lambda-with-event-bridge-by-terraform

## 関連記事
Go言語で記述したスクリプトを、**AWSのLambdaにTerraformを用いてデプロイする**機会があり、その過程の試行錯誤を整理して一連の記事にまとめました。

この記事はそのうちの3本目として、GoのスクリプトをAWS EventBridgeから定期実行する構成をデプロイしてみたいと思います。

– [zipファイルを用いてGo言語の処理をAWS Lambdaにデプロイする](https://qiita.com/mochi_2225/items/1b645f87148899f1bc09)
– [Dockerイメージを用いてGo言語の処理をAWS Lambdaにデプロイする](https://qiita.com/mochi_2225/items/000ee604b3a274b6b62d)
– **Even

元記事を表示

AWS LambdaにGo言語のスクリプトをDockerイメージでデプロイする [Terraformを使用]

## 要約
最終的なソースコード全体は以下のリンクからご確認いただけます。

https://github.com/mochi-yu/qiita-material/tree/main/golang-lambda-by-docker-with-terraform

## 関連記事
Go言語で記述したスクリプトを、**AWSのLambdaにTerraformを用いてデプロイする**機会があり、その過程の試行錯誤を整理して一連の記事にまとめました。

この記事はそのうちの2本目として、Dockerイメージを用いてLambdaにスクリプトをデプロイしてみたいと思います。

– [zipファイルを用いてGo言語の処理をAWS Lambdaにデプロイする](https://qiita.com/mochi_2225/items/1b645f87148899f1bc09)
– **Dockerイメージを用いてGo言語の処理をAWS Lambdaにデプロイする**(この記事)
– [EventBridgeからAWS Lambdaを定期実行する処理をデプロイする](https://qiita.com/mo

元記事を表示

AWS LambdaにGo言語のスクリプトをzipファイル形式でデプロイする [Terraformを使用]

## 要約
最終的なソースコード全体は以下のリンクからご確認いただけます。

https://github.com/mochi-yu/qiita-material/tree/main/golang-lambda-by-zip-with-terraform

## 関連記事
Go言語で記述したスクリプトを、**AWSのLambdaにTerraformを用いてデプロイする**機会があり、その過程の試行錯誤を整理して一連の記事にまとめました。

この記事はそのうちの1本目として、zipファイルを用いてLambdaにスクリプトをデプロイしてみたいと思います。

– **zipファイルを用いてGo言語の処理をAWS Lambdaにデプロイする**(この記事)
– [Dockerイメージを用いてGo言語の処理をAWS Lambdaにデプロイする](https://qiita.com/mochi_2225/items/000ee604b3a274b6b62d)
– [EventBridgeからAWS Lambdaを定期実行する処理をデプロイする](https://qiita.com/mochi_22

元記事を表示

【Go言語】名前付き戻り値

# はじめに

Goでは名前付き戻り値(Named Return Value)はあまり使われない。
この記事では、名前付き戻り値の使い方を解説します。

# 名前付き戻り値とは?

名前付き戻り値を使うと、引数なしの空return文を呼び出せる。

“`go
func f(a int) (b int) {
b = a
return
}
“`

上記の場合だと、戻り値はbの値となる。

# 名前付き戻り値の使用例

非公開のインターフェイスの場合ドキュメントは必須ではない。以下の例は、住所から座標を取得するメソッドを持つインターフェイスである。

“`go
type locator interface {
getCoordinates(address string) (float32, float32, error)
}
“`

ドキュメントがないと、`float32`の情報だけでは、緯度か経度かが不明瞭である。
そこで以下のように、名前付き戻り値を使用することで、シグニチャを明示する。

“`go
type locator interface {
getC

元記事を表示

Go言語のContextについて

contextとは?

Go言語ではcontextパッケージを利用して、WithTimeout、WithCancel、WithDeadlineを使い、
main goroutineからsub goroutineを一斉キャンセルできます。
下記でcontextを活用する3つのパターンを紹介します。

WithTimeout

タイムアウトを経過したときに一斉にsub goroutineをキャンセルする処理を書いていきます。
contextのDoneチャネルを使う事によってsub goroutinesの処理を一斉にキャンセルすることができます。

“`Go
package main

import (
“context”
“fmt”
“sync”
“time”
)

func main() {
var wg sync.WaitGroup
// 400ミリ秒後にタイムアウトを設定
ctx, cancel := context.WithTimeout(context.Background(), 400*time.Millisecond)

元記事を表示

Go速查表の宣伝記事 cheat sheets

[![go-preview.png](https://cheatsheets.zip/assets/image/go-preview.png)](https://cheatsheets.zip/go)

こんにちは、皆さん!Go言語を学んでいる方々に朗報です!Goの速查表が登場しました!基本的な構文やメソッドをすぐに確認できるので、学習効率がアップします。速查表の詳細は[こちら](https://cheatsheets.zip/go)からチェックしてください。

## 速查表の内容

### はじめに

#### hello.go

“`go
package main

import “fmt”

func main() {
fmt.Println(“Hello, world!”)
}
“`

#### 実行方法

“`sh
$ go run hello.go
Hello, world!
“`

または、GoのREPLで試してみてください。

### 変数

“`go
var s1 string
s1 = “Learn Go!”

// 複数の変数を一度に宣言
va

元記事を表示

【SQL】prepare文って何?

# SQLのPrepare文とミドルウェアの仕組み:

SQLのPrepare文は、パフォーマンスの向上やセキュリティの強化を目的とした重要な技術です。ミドルウェアの仕組みとPrepare文の仕組みを解説します。さらに、PythonとGoでの実装例も紹介します。

## 1. ミドルウェアの解説

多くのミドルウェアは以下の主要なコンポーネント構成について解説します。

1. **パーサー(Parser)**: parse(解析する)+ er(人/もの)= 解析する人
SQLクエリを解析し、構文エラーや文法エラーをチェックします。クエリの構造を内部的な表現に変換します。
例えば、ユーザ情報を管理するテーブルであるuser_infoテーブルがあるとします。
開発者の誰かがよくテーブルを確認せずに以下のようなSQLを書いたとします。
SELECT * FROM users;
上記のクエリは、FROM句に指定すべきテーブル名が誤っています。
この時、「そんなテーブルないよ!?」というエラーが発生しますが、これはパーサーがテーブル情報を見て、「usersテーブルなんてないじゃん!」とエラーを出

元記事を表示

Go 1.21 以降のスライスのソート

はじめまして、しろしゅんと申します。

最初の記事としては若干ニッチなテーマですが、Go 言語におけるソートについて書いてみました!
Go を最近始めた方や日頃からよく書く方を想定しています。

Go 1.21 で `slices` パッケージが正式に導入され、標準ライブラリでのスライスに対する操作、例えば比較やソート、最大・最小の算出などの機能が拡充されました。
すべての関数でジェネリクスが使用されているため、従来の標準ライブラリに比べ利用者側での書きやすさや拡張性が向上しています。

スライスをソートする関数については、従来の `sort` パッケージと比べると、大小関係を判定する関数が `less func(a, b int) bool` から `cmp func(a, b E) int` に変わったことが大きな変更点と言えるでしょう。

この記事では、新しいソート関数の使用例と、従来ソートに使用されていた `less` 関数から `cmp` 関数に変わった経緯などに触れていきます。

## `func SortFunc[S ~[]E, E any](x S, cmp func(

元記事を表示

GoのastutilでAST処理をしてみる

前回の記事: [Goの構文解析に入門してみる #Go – Qiita](https://qiita.com/ssc-ynakamura/items/142ce6b729299d82d039)

少し前にGoの構文解析に入門してみたわけですが、前回の記事の最後では[`golang.org/x/tools/go/ast/astutil`](https://golang.org/x/tools/go/ast/astutil)(以下、`astutil`)という便利パッケージがあることに触れました。
今回はこの`astutil`パッケージを使ってみたいと思います。

標準の`ast`での処理を踏まえた上での`astutil`なので、前回の記事もご一読いただけると、より一層理解しやすくなるかと思います。
「AST(抽象構文木)って何?」という方も、前回の記事をご一読ください。

## 本記事の動作環境

本記事は次の環境で動作確認しながら書きました。

– macOS Ventura
– Go 1.22

OSについては特に環境依存はないかと思います。

Goのバージョンについては、大きく離れてい

元記事を表示

【Go1.23】range over func原理主義者のためのモジュール作りました【itermania】

# TL; DR

https://github.com/Syuparn/itermania

“`go
prime := Bind(Inc(2), func(n int) Gen[int] {
return Where(Const(n), All(Not(Eq(Mod(Const(n), Range(2, n, 1)), Const(0)))))
})

for i := range Head(prime, 10)() {
fmt.Println(i)
}
“`

“`
2
3
5
7
11
13
17
19
23
29
“`

# はじめに

Go1.23から、for文の `range` に関数を指定することができるようになります。これによって、スライスを用いない反復処理をシンプルに書くことができます。

“`go
// 0~2を繰り返すイテレータ
func rotate(yield func(int) bool) {
i := 0
for {
// yieldの引数がループ変数として渡される
if !yield(i) {
// for文本体のループ

元記事を表示

【Go言語】値レシーバ v.s. ポインタレシーバ

# はじめに

値レシーバとポインタレシーバどちらを使うべきかをこの記事では解説します。

# 値レシーバの例

[Go Playground](https://go.dev/play/p/45PS4ZLjgXd)

“`go
type customer struct {
balance float64
}

func (c customer) add(operation float64) {
c.balance += operation
}

func main() {
c := customer{balance: 100.0}
c.add(50.0)
fmt.Printf(“balance: %.2f\n”, c.balance) // balance: 100.00
}

“`

customerのbalanceフィールドの値は変更されない。

# ポインタレシーバの例

[Go Playground](https://go.dev/play/p/xt2JGopkxO_f)

“`go:ポインタレシーバ
type customer struct {
balanc

元記事を表示

[Go/DDD] BackEnd Portfolio 作成

# 前段
転職活動の一環で、簡易なバックエンドポートフォリオを作成しました。

https://github.com/tadasi/portfolio

なおコードを見せるのが目的なため、アプリケーションの中身は簡易な TODO アプリとしました。

作業時間短縮のために画面も用意していなければデプロイも想定していないので、Docker を立ち上げてローカルで curl を叩くとローカル MySQL で CRUD 処理ができるというだけの機能しか有しておりません。

(なお同様の理由で単体テストの実装も割愛しております)

# 概要
今回「ドメイン駆動設計(DDD)」を意識しました。

業務上でも一部 DDD の設計が取り入れられてはおりますが、本ポートフォリオにおいてはオリジナルの極めてシンプルな構成にしております。

# ディレクトリ構成
大まかには、下記のような構成です。
“`
.
├── api/
│ └── openapi
├── application/
│ ├── server/
│ │ └── main.go
│ └── usecases/

元記事を表示

Goでメモリアロケータを実装&ベンチマークで比較してみた

## はじめに

:::note warn
警告
以下の記事、実装はあくまで検証用です。
:::

Go 1.20 で 標準パッケージの実験的なものとして、 arena パッケージが提供されました。
[Goのメモリ管理 / Memory management in Go – Speaker Deck](https://speakerdeck.com/ymotongpoo/memory-management-in-go) のスライドを見ていて、メモリ割り当てサイズにより割り当て速度がどのように変化するのか、またメモリアロケータを実装して速度を改善することができるのかと思い今回の検証を試してみることにしました。

## TL;DR

– Goにおいて、ほとんどの通常用途ではメモリ管理の実装は不要。
– 今回の検証においては、1MB近いデータを確保する場合は、自作メモリアロケータ(TLSF)の方が約25倍ほど高速。
– ただし、unsafe.Pointerを扱わなくてはいけないため、メモリ管理のコストを払う必要がある

## 検証イメージ

アプリケーションから見た時のメモリ割り当て

元記事を表示

Go言語のAPIサーバをマルチステージビルドでAWS ECSにデプロイしたら、ヘルスチェックが通らなかった

## 要約
はじめは、ヘルスチェックに`curl`コマンドを用い、Go言語のバイナリ実行のステージに`distroless`イメージを利用する設定にしていました。

ですが、`distroless`イメージは極力コマンドなどを削った環境であり、`curl`コマンドもインストールされていないようで、ヘルスチェックが行えませんでした。

対処法の候補はいくらかあるかと思いますが、私は`distroless`イメージの使用を辞め、**`alpine`イメージを使用する**ようにし、ヘルスチェックのコマンドも`curl`ではなく`wget`を使うように変更しました。

“`Dockerfile
HEALTHCHECK CMD wget –quiet –spider http://localhost:1323/ || exit 1
“`

## 背景
### 元々のコンテナイメージ
普段Go言語のAPIサーバを構築する際、実行環境はDockerで構築しています。いままでは以下のようなDockerfileでGo言語のプログラムを実行していました。

“`Dockerfile:Docker

元記事を表示

【Go言語】部分文字列

# はじめに

スライスや配列をスライス化する際に、メモリリークが発生する可能性がありますが、文字列でも同様の事象が考えられます。(スライスについては以下を参照)

https://qiita.com/twrcd1227/items/989d8d553fc6913f01f3

# 部分文字列

“`go
func main() {
s1 := “Hello”
s2 := s1[:5]
fmt.Println(s2) // Hello
}
“`

`s2`は`s1`の部分文字列となっている。ただし、最初の5つのruneからではなく、5バイトから文字列を作成している。

ちなみに、runeについては以下で詳しく解説しています。

https://qiita.com/twrcd1227/items/45d3fb4be5bce334fae9

エンコードすると複数バイトのruneになる場合は、上記のような部分文字列は使用してはいけない。

[Go Playground](https://go.dev/play/p/8Ki9LZvuCzG)

“`go
func main() {

元記事を表示

OTHERカテゴリの最新記事