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

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

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

元記事を表示

golang-migrateを使ってみた(CLI編)

dockerで環境を作成しています
“`
使用イメージ : postgres:16
os : Debian GNU/Linux 12 (bookworm)
postgresql : psql (PostgreSQL) 16.4 (Debian 16.4-1.pgdg120+2)
“`

### golang-migrateをインストール
“`
# apt-get update && apt-get upgrade -y
# apt-get install tar gzip curl vim
# curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.0/migrate.linux-amd64.tar.gz | tar xvz
# mv ./migrate /usr/bin/migrate
“`
利用できるかチェック
“`
$ migrate -help
“`
### 公式のPostgreSQLのチュートリアルを参考に進めていく

データベースの作成
“`
psql -h local

元記事を表示

libp2pでピア間をストリーム通信

[libp2p](https://libp2p.io/) という P2P 用のネットワークライブラリがあります。
Go言語用のライブラリ [go-libp2p](https://github.com/libp2p/go-libp2p) を使ってピア間のメッセージ通信を試してみました。

# はじめに

今回は、libp2p のノードを 2種類(とりあえず server と client にしました[^1])実行し、以下のようなメッセージ通信を libp2p のストリームで実施します。

[^1]: P2Pに適さない表現かもしれませんが

“`mermaid
flowchart LR

client –>|”now”| server
server –>|”<現在時刻>“| client
“`

client が “`now\n“` というメッセージを送信すると server から現在時刻を返します。
client はこれを 3秒毎に 5回繰り返して終了する事にします。

改行(“`\n“`)をメッセージの区切り文字とします。

# (a) アドレス指定の接続

まずは、接

元記事を表示

Goの値レシーバとポインタレシーバの違い

# Golangの値レシーバとポインタレシーバの違い

Golangの値レシーバとポインタレシーバの振る舞いの違いについて備忘録です。
また、ポインタから値レシーバの暗黙呼び出しについても書いておきます。

Golangには値レシーバとポインタレシーバがあります。

構造体
“`
type Account struct {
Id int
}
“`

値レシーバ
“`
func (a Account) Set(id int) {
a.Id = id
}
“`

ポインタレシーバ
“`
func (a* Account) Set(id int) {
a.Id = id
}
“`

## 値レシーバとポインタレシーバの振る舞いの違い

値レシーバはメソッド呼び出しごとに変数がコピーされてその変数に対して実行されます。なので、宣言じの変数の値は変更されません。

ポインタレシーバは、宣言時のメモリアドレスを持つ変数に対してメソッドが実行されます。
以下の例では値レシーバのメソッド`Add`は何回呼び出しても元の変数の値はそのままです。
ポインタレシーバのメソッド`AddPoi

元記事を表示

Golangの構造体のポインタ配列

# Golangの構造体のポインタ配列

Golangの構造体(Golangでなくてもそうかも)は、メモリ使用量が地味に多いので、ポインタ配列を使いまくるのがコストパフォーマンス面で良さそうなので使いまくるために備忘録。

## 使いまくるポインタ例

“`
type Account struct{
id int
name string
}
“`

でこういうのたち。ポインタとポインタの配列。
“`
*Account
[]*Account
“`

こっちじゃない。これは配列のポインタ。
“`
*[]Account
“`

## ポインタ配列

ポインタ配列の方が速い。使いまくる。

“`
package main

import (
“fmt”
)

// todo
// requirement
// Account is struct
// Accounts has an Account array defined as a pointer in field

type Account struct {
id int
name string
}

ty

元記事を表示

Go言語で平衡二分探索木の AVL木 を実装してみた

# はじめに
どうも、わたしです。今回は Go言語(Golang)で **「AVL木」** を実装してみました。データ構造についてはあんまり理解が乏しいですが、自分が学んだことをアウトプットしたいので記事に書きます!!

なるべく詳しく書くつもりなので、てっとり早く実装どうやってやるんだよという方は以下のわたしが参考にした方(karaskさん)の Github をご覧ください。

https://github.com/karask/go-avltree/blob/master/avltree.go

この記事はまず二分探索木について話して、そのあと平衡二分探索木の話、AVL木についてと、メインの実装というようにまとめたいと思います。

# 動機
いまわたしは Go で AtCoder の競プロを頑張っているんですが [ABC352 の D 問題](https://atcoder.jp/contests/abc352/tasks/abc352_d) に挑戦した際、わかんなーいってなって解説見たんですが「平衡二分探索木」を使いましょうってあってなんじゃそれはとなりました。調べてみると Go

元記事を表示

GoでHTTPサーバーを構築して複数のAPIエンドポイントを作成する方法

この記事では、Goの標準ライブラリ `net/http` を使って、簡単なHTTPサーバーを立ち上げ、複数のAPIエンドポイントを作成する手順を解説します。これにより、ブラウザやHTTPクライアントからリクエストを受け取り、JSONデータやレスポンスを返すAPIサーバーを構築できます。

## 必要な準備

1. Goがインストールされていること(バージョン1.16以上推奨)
– インストールされていない場合は、公式サイトからインストールします:[Go公式サイト](https://golang.org/dl/)
2. ターミナル(またはコマンドプロンプト)

## サーバーコードの実装

以下のコードを使って、複数のAPIエンドポイントを持つサーバーを作成します。

“`go
package main

import (
“encoding/json”
“fmt”
“net/http”
)

// User 構造体
type User struct {
ID int `json:”id”`
Name string `json:”name”`
Age

元記事を表示

Goのnet/httpパッケージ チートシート

# Goの`net/http`パッケージ チートシート

Goの`net/http`パッケージに関する詳しいチートシートです。コード例とコメントを含めているので、参考にしてください。

## 1. 基本的なHTTPサーバー

“`go
package main

import (
“fmt”
“net/http”
)

// HTTPリクエストを処理するハンドラ関数
func handler(w http.ResponseWriter, r *http.Request) {
// クライアントにレスポンスを返す
fmt.Fprintf(w, “こんにちは、あなたはこのURLをリクエストしました: %s
“, r.URL.Path)
}

func main() {
// ルートパス”/”にハンドラ関数を登録
http.HandleFunc(“/”, handler)

// ポート8080でHTTPサーバーを起動
fmt.Println(“ポート8080でサーバーを起動します”)
err := http.Lis

元記事を表示

OTHERカテゴリの最新記事