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

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

Go言語でシンプルなWebアプリケーションを作る:ワークアウト記録アプリ

![スクリーンショット 2024-10-05 14.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/839ed97c-12c2-4d19-b467-5012b6513933.png)

## はじめに

今回は、Go言語(Golang)を使用して、シンプルなワークアウト記録Webアプリケーションを作成してみました。この記事は、私がGo言語の基本を学ぶための備忘録として書いています。データベースにはPostgreSQLを使用し、Dockerを利用して環境を構築します。

## プロジェクト構造

まずは、プロジェクトの構造を見てみましょう:

“`
/my-go-workout-app
├── Dockerfile
├── docker-compose.yml
├── go.mod
├── go.sum
├── init.sql
├── main.go
├── handlers
│ └── records.go
│ └── down

元記事を表示

GoのFunctional Options Patternのユースケースを実務から紹介する

## サマリ
– 実務においてFunctional Options Patternを活用できた例を紹介します
– 具体的には、構造体が階層構造になっている場合で、初期化時の子要素の構造体作成の制御に利用したケースを紹介します

## はじめに
Goを実務で使うようになって、学び始めてから1年以上経ちましたが、なかなかアウトプットができていなかったので初めて記事を書いてみました。

今回は、GoのFunctional Options Patternについて、実務で利用できたケースについて紹介できればと思います。

## Functional Options Patternとは?

Functional Options Patternは、Go言語でよく使われるデザインパターンの一つです。
構造体の初期化時に、特定のオプションフィールドを関数として渡すことにより、構造体の設定を行うものです。

このパターンを用いると、構造体の初期化時に多くの引数を渡す必要がある場合でも、可読性を損なわずにオプションを追加・管理することが可能になります。

今回は詳細の解説は行いませんが、以下の記事がシンプル

元記事を表示

GoのbigCacheのサンプルコード

## リポジトリ

[https://github.com/allegro/bigcache](https://github.com/allegro/bigcache)

## Example(echo使用)

“`go
// キャッシュの設定
config := bigcache.Config{
// シャードの数(2のべき乗でなければならない)
Shards: 1024,
// エントリが削除されるタイムアウトの時間
LifeWindow: 10 * time.Minute,
// 期限切れのエントリを削除する間隔
CleanWindow: 30 * time.Second,
}

// キャッシュの初期化(アプリケーション実行時のみ行うmain.goやroute.goなど)
cache, err := bigcache.NewBigCache(config)
if err != nil {
e.Logger.Fatal(err)
}

// キャッシュお試しのルート
cacheGroup := publicGroup.Group(“/cache”)
cac

元記事を表示

golang-migrateを使ってみた(アプリケーション編)

### ソースコード
“`go
package main

import (
“database/sql”
“fmt”
“log”

_ “github.com/lib/pq”
“github.com/golang-migrate/migrate/v4”
“github.com/golang-migrate/migrate/v4/database/postgres”
_ “github.com/golang-migrate/migrate/v4/source/file”
)
func main(){

// PostgreSQL に接続
db, err := sql.Open(“postgres”, “postgres://postgres:password@localhost:5432/dbname?sslmode=disable&search_path=test_schema”)
if err != nil {
log.Fatalf(“Failed to connect to the database:

元記事を表示

Goでファイルを書き込むと書き込み先ファイルが消えているのに読み込める

## 症状
### 準備
以下のようなログラムを作成した.
“`go
package main

import (
“fmt”
“io”
“os”
“path/filepath”
)

func main() {
path := “~/.config/tilde-expan/hoge.txt”
write(path)
read(path)
}

func write(path string) {
dir := filepath.Dir(path) // ディレクトリが存在しない場合は作成する
if _, err := os.Stat(dir); os.IsNotExist(err) {
err = os.MkdirAll(dir, 0755)
}

file, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
defer file.Close()

fmt.Fprintln(file, “test”)
}

func read(path string) {
file, _

元記事を表示

gofmtについて

## gofmtについて

goに標準で搭載されているコード整形機能のこと。
`fmt.Println()`ばかり使っていたのでこの機能を知った時はとても便利な機能があるなと思いました。

### 例)hogehoge.goのコード
“`
package main

import “fmt”

const (
idKey = “id”
nameKey = “name”
runeKey = ‘a’
)

func main() {

for i := 0; i < 10; i++ { fmt.Println(i) if i == 5 { break } } t := 10 fmt.Println(t) fmt.Println(1 + 1, 2+2) fmt.Println("1 + 1 =", 1+1) fmt.Println("10 - 1", 10-1) fmt.Println("10 / 2", 10/2) fmt.Println("10 / 3", 10/3) fmt.Println("10.0

元記事を表示

[Go] 構造体のKey/Value を出力する

“`go
package main

import (
“fmt”
“reflect”
)

type User struct {
ID string
Foo string
Bar int
pri string
Pub int
}

func main() {
user := User{“id1”, “foo”, 2, “skip me without panic”, 4}
fmt.Println(user.String())
//ID: id1
//Foo: foo
//Bar: 2
//Pub: 4
}

func (u User) String() string {
str := “”
fa := reflect.ValueOf(u)
for i := 0; i < fa.NumField(); i++ { if !fa.Field(i).CanInterface() { // skip private for avoid panic continue } str += fmt.Sprintf("%v: %v\n", fa.

元記事を表示

Goのメモリアライメント ~Goの構造体におけるメモリ使用量の最適化~

株式会社Schooの [@hiroto__1220](https://x.com/hiroto__1220)です!
Goのメモリアライメントと構造体のフィールドを定義する順番によるメモリ使用量の変化について調査してみました!

## 簡単にまとめると
– CPUが効率的に処理できるよう、メモリアライメントにより変数のアドレスは特定の倍数になるように調整される
– 構造体のフィールドを定義する順番によって、メモリ使用量は変化する

## 型それぞれのサイズ
“`go
func main() {
var num1 int64
fmt.Printf(“Size of int64: %d bytes\n”, unsafe.Sizeof(num1))

var num2 int32
fmt.Printf(“Size of int32: %d bytes\n”, unsafe.Sizeof(num2))

var num3 float64
fmt.Printf(“Size of float64: %d bytes\n”, unsafe.Sizeof(num3))

var nu

元記事を表示

開発用適当ツールはGoで作るのがオススメ

## 開発用適当ツールとは?

開発していると、たまに何かしらプロジェクト内で開発者用や運用者用にテストデータを作成したり、DBやAPIに繋いでCSVやExcelを出したりする**名もなきツールが大量に必要になってきますよね?** 配布して他の人にも使ってもらったりしたくなりますよね?

これが開発用適当ツール[^1]です。

[^1]: 一部の人は治具と呼んでいるかもしれません

そういった**開発用適当ツールをGoで作ってみたら案外体験が悪くなかった**のでシェアしたいと思います。

## どうやって開発用適当ツールを作るか?

既存プロジェクトにそのままGoのプロジェクトレイアウトを重ねていきます。

具体的には以下のような感じです。

“`
project-root-directory/
プロジェクトの既存ファイル
go.mod
go.sum
cmd/
ツール1/
main.go
ツール2/
main.go
internal/ (もしくは分かりやすいディレクトリ)
(main.go に入らなかった共通処理など

元記事を表示

goのテストでファイルが削除できずにエラーになっていた件

## 発生していた問題

#### 原因のテストコード
goのテストでは、t.TempDir()というフォルダを使用するとテスト終了時に勝手に該当のフォルダを削除してくれる機能があります。
“`
testFile, err := os.Create(t.TempDir() + “/” + fileName)
if err != nil {
t.Fatal(err)
}
“`

実際にテストを実行したところ以下のようなエラーが出ていた。
“`
c:\…\testing.go:1232:
TempDir RemoveAll cleanup: remove
C:\…\test_for_delete.txt:
The process cannot access the file because it is being used by another process.
“`

### 解決策
os.Createで作成したファイルをCloseしていなかったことが原因でした。
“`
testFile.Close()
“`

最終的なコードは以下のようになりました。
“`

元記事を表示

Go言語でSNMPのMIBファイルを読み込む方法

# はじめに

以前、Go言語からSNMPのアクセスをするプログラムの説明で

https://qiita.com/twsnmp/items/2986b696cced09820291

という記事を書きました。その余談に書いた、もっと人にやさしくする方法の解説です。
SNMPのMIBファイルをASN.1といフォーマットで定義します。
このファイルを読み込めるgosmiパッケージ

https://github.com/sleepinggenius2/gosmi

の紹介です。

# gosnmiのパース処理のサンプル

https://github.com/sleepinggenius2/gosmi/tree/master/cmd/parse
にMIBファイルを読み込むサンプルプログラムがあります。

“`go
package main

import (
“log”
“os”

“github.com/alecthomas/repr”
“github.com/sleepinggenius2/gosmi/parser”
)

func main() {
module, er

元記事を表示

Bubble Teaを使った選択肢と入力フォームの切り替え処理

## 目次

1. [はじめに](#1-はじめに)
2. [環境](#2-環境)
3. [Bubble Tea フレームワークの紹介](#3-bubble-teaフレームワークの紹介)
4. [プロジェクトの構成とセットアップ](#4-プロジェクトの構成とセットアップ)
– [プロジェクトのディレクトリ構成](#41-プロジェクトのディレクトリ構成)
– [プロジェクトのセットアップ](#42-プロジェクトのセットアップ)
– [依存パッケージのインストール](#421-依存パッケージのインストール)
– [`main.go`の作成](#422-maingoの作成)
– [`terminal.go`の作成](#423-terminalgoの作成)
5. [作成手順](#5-作成手順)
– [構造体の作成(model, State, UserInfo…)](#51-構造体の作成model-state-userinfo)
– [初期化関数の作成(Init, InitialModel)](#52-初期化関数の作

元記事を表示

GoでHTTPサーバーを構築: ミドルウェアとインメモリデータ管理を使ったデータ処理

## はじめに
前回の記事では、Go言語で基本的なHTTPサーバーの構築手順を解説しました。
今回の記事では、前回に引き続きリクエストを処理する際のミドルウェアの使用法、データベース接続の代わりにインメモリでデータを管理する方法を紹介します。
https://qiita.com/h-i-ist/items/ca33366060b47acc6fe8

## 1. プロジェクトの構成

“`bash
go-http-server/
├── cmd/
│ └── app/
│ └── main.go
├── internal/
│ ├── handlers/
│ │ └── handler.go
│ └── middleware/
│ └── logging.go
├── storage/
│ └── memory.go
└── go.mod
“`

### 各フォルダーの役割
前回の記事に加え、今回新たに **middleware**と **storage** ディレクトリを追加しています。

– **cmd/:** アプリケーションの

元記事を表示

Go言語でsFlowのFlowSampleをデコードする方法

# はじめに

前回の記事

https://qiita.com/twsnmp/items/17936394543d29bee00e

の続きです。
前回の記事では、受信したFlowSampleを

“`go
case *sflow.FlowSample:
log.Printf(“FlowSample from %s”, raIP)
for _, record := range s.Records {
log.Printf(“%+v”, record)
}
“`

のような処理で表示していたので

“`teminal
2024/09/29 17:10:18 RawPacketFlow: {Protocol:1 FrameLength:146 Stripped:4 HeaderSize:128 Header:[80 0 0 4 0 0 0 37 54 171 119 83 8 0 69 0 3 29 103 109 0 0 57 17 143 109 198 41 0 4 192 168 1 32 0 53 136 185 3 9

元記事を表示

クレジットカードの明細を検索できるサービスをモダンな技術セットで作ってみた

個人開発したアプリの紹介記事です。

## どんなアプリか?

皆さん、毎月クレジットカードの明細は確認していますか?

クレジットカードを使うとき、見慣れない明細を見たとき不安になりませんか?

クレジットの明細を投稿・閲覧できるサイトをGolangとAWSを用いて作成しました。

https://meisaicheck.tech/

## 技術セット
今回は、S3の静的ホスティング機能を使いました。また、独自ドメインを取得して、Cloudfrontを使うことで、hptts通信でアクセスできるようにしました。
ホスティングしているのは、htmlファイルですが、デザインはtailwindCssを使い、jsフレームワークにalpine.jsを使いました。
バックエンドには、lambdaとgolangを用い、DBとしてDynamoDBを採用しました。

自分としては、lambdaのハンズオンを少しやったことがある程度で、golangとDynamoDBは初めて触りました。
それほど難しい操作は実装していませんが、それでも難しかったです。

## 技術的に苦労したことや発見など
今回、S3の静

元記事を表示

gomockでmockを作ってみる

# gomockとは?
gomockとは、インターフェース定義からモックの生成を行うことができるgoのライブラリで、go公式から出されています。

https://github.com/golang/mock

しかし、READMEには

>Update, June 2023: This repo and tool are no longer maintained. Please see go.uber.org/mock for a maintained fork instead.

と書かれており2023でメンテナンスが終了しているようでした。

READMEにも書かれているように`go.uber.org/mock`がその代わりとして使用されています。

`go.uber.org/mock`は、かの有名なUberEatsを運営しているUberが`gomock`のメンテナンスを引き継いだライブラリです。

今回は、`go.uber.org/mock`でモックを作成してみようと思います。

https://github.com/uber-go/mock

# そもそもモックって?

元記事を表示

ローカルテスト用SMTPメールサーバは Mailpit がオススメ!

## はじめに

長らくローカルテスト用のメールサーバとして [MailHog](https://github.com/mailhog/MailHog) ([DockerHub](https://hub.docker.com/r/mailhog/mailhog)) を使ってきたのですが、以下のような不満がありました。

– 今現在(2024)メンテナンスが行われていない
– ローカル開発用とはいえ、UXが厳しい(日本語を受け付けてくれない)
– アーキテクチャが amd64 しか対応していない

そこで、MailHogよりベターな選択肢はないか調査してみたところ、 [Mailpit](https://github.com/axllent/mailpit) ([DockerHub](https://hub.docker.com/r/axllent/mailpit)) が以下の点で良いと感じ実際に使っているので、この記事で紹介します。

– 今現在(2024)メンテナンスが行われている
– 良いUX。ちゃんと日本語でメールを検索できる
– アーキテクチャとして arm にも対応している (

元記事を表示

PHP(動的型付け)・PHP(動的型付け+型指定)・Go(静的型付け)の比較

型に注目してPHPとGoを比較してみます。

1年ほど前まではPHPで型を指定せずに実装していたので、その視点からまとめてみました。

## 動的型付け(PHP)の主なメリットデメリット

### メリット

少ない工数で実装が可能。型を指定しなくて良いため、コード量が少なくなる、及び型について考える必要がない。経験の少ないエンジニアでも容易に実装可能。

### デメリット

型の指定がないため、実装時に型の違いに気づけず、予期せぬバグが発生しやすい。また、型がバグの原因である場合に原因の追求に時間がかかる。

型の指定がないことで、メソッドの引数を見た際にどのような内容や意図の引数なのか分かりにくい。毎回、元のデータを追っていくのが手間となる。

例1)記事詳細情報取得
“`
class ArticleService
{
/**
* 記事詳細情報取得
*/
public function detail($id)
{
return [$article, $dramaList, $related]

元記事を表示

【Go】「deferは関数終了時に実行される」その認識、大丈夫?

# はじめに
* Goの`defer`について「呼び出し元の関数の終了時に実行されるんだな!」と軽く理解していませんか?(私もその一人でした、偉そうなタイトルですいません…)
* ですが、そのような認識では説明できない動作に困惑する時が来るかもしれません
* この記事では、私が実際に犯した勘違いを例に、deferの正しい動作を理解するためのポイントを解説します

# 前提:deferとは?
前回、deferの基本的な特徴をまとめた記事を書きました。一言で言うと、**関数の遅延実行の仕組み**です。詳しくはこちらをご覧ください。

https://qiita.com/kogamochiduki/items/abc8548fad2e8e382508

# 私の勘違い
Goのdeferを初めて触れたとき、私はこう思っていました。
#### deferは関数の終了時に実行される。つまり、関数を抜けた後に一気に処理がされるんだな!!
しかし、この認識は完全に正確ではありません。特にdeferの引数が関数呼び出しを含む場合、この認識だと間違った結果になります。私がその間違いに気づいたのが次のソ

元記事を表示

Go言語でsFlowのパケットを受信する方法

# はじめに

Go言語でsFlowのパッケットを受信して処理する方法の紹介です。sFlowのサーバーを開発するGo言語のパッケージはありますが、うまく動かなかったので、sFlowのパケットをデコードするパッケージ

https://github.com/Cistern/sflow

を使ってサーバーを作る方法を紹介します。

# sFlowパケット受信プログラム

“`go
package main

import (
“bytes”
“log”
“net”

“github.com/Cistern/sflow”
)

func main() {
sv, err := net.ListenPacket(“udp”, “:6343”)
if err != nil {
log.Fatalln(err)
}
defer sv.Close()
data := make([]byte, 8192)
for {
l, ra, err := sv.ReadFrom(data)
if err != nil {
log.Println(err)
conti

元記事を表示

OTHERカテゴリの最新記事