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

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

GolangのYamlパッケージのバグを見つけた話

## 初めに

弊社プロダクトでは設定に関する項目をyamlで記述していてAPI起動時にUnmarshalしているのですが、その結果が期待していたものと異なることが以前発生したので原因は何だったのか、どうやって突き止めたのかをまとめてみました。
とりあえず原因だけ知りたいという方は[こちら](https://github.com/go-yaml/yaml/issues/1035)のissueを見て頂くと良いかと思います。

## 使用環境
[yamlライブラリ](https://github.com/go-yaml/yaml)
“`bash
% go version
go version go1.21.1 darwin/amd64
“`

## バグの詳細
yaml上に書いた一部の設定が構造体に反映されませんでした。
具体的には次のようなyamlを用意した時に、 `merger_val` の値がマッピング先に反映されていませんでした。
“`config.yaml
mergee_param: &mergee
param_key:
keywords: []

merger

元記事を表示

Goのcontextを使ってみる

## WithCancel

WithCancel()でキャンセル用のcontextを作成しておき、2秒待ってから、cancel()を実行して処理を中止するように、longRunningTask()に伝えています。

こうすることで、それ以上実施する必要のない処理を止めることができるようになります。

“`go
package main

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

// 長時間かかる処理をシミュレートする関数
func longRunningTask(ctx context.Context) {
select {
case <-time.After(5 * time.Second): // 処理が完了した場合 fmt.Println("Task completed") case <-ctx.Done(): // キャンセルやタイムアウトが発生した場合 fmt.Println("Task canceled:", ctx.Err()) } } func main() { // キャンセル可能なコンテキストを生成

元記事を表示

【Go言語】ジェネリクス

# はじめに

今回はGoのジェネリクスの使い方をまとめました。
スライドもあります。

# any

## anyとは

anyとは空インターフェイス`interface{}`のエイリアスで、どんな型でも保持することが可能。

以下は実際にanyにいろんな型を入れてみた例。

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

“`go
func main() {
var i any
i = 42 // int
i = “foo” // string

i = struct {
s string
}{
s: “bar”,
} // struct

i = func() {} //関数

元記事を表示

【初学者はとりあえずこれでOK】とにかく書いてみるGraphQL スキーマ設計3ステップ

## はじめに
この記事が、GraphQL はじめてみたいけど、スキーマ設計とかクライアントライブラリとか、色々な情報が溢れていてわからないといった初学者向けに、まずはこれで書いてみよう!と迷わず実際に触るための一助になれば嬉しいです。

## スキーマファーストとコードファースト

GraphQLを使ったAPIの開発では、**2つの進め方があります。**
GraphQLってなにー??な状態の方はまず[こちらの記事](https://speakerdeck.com/kazukihayase/graphqlkuraiantonoji-shu-xuan-ding-2023dong?slide=14)の前半部分をどうぞ。

進め方1つ目の**スキーマファースト**では、まずGraphQLスキーマ(型定義)をサーバーチーム、フロントチームが一緒に話して作成します。作成したスキーマの設計を基盤として、両チームが実装を並行して進めていくことができます。

2つ目の**コードファースト**は、GraphQLスキーマ(型定義)を、主にサーバーチームが作成します。**まずサーバーのコードを書き、そこか

元記事を表示

Goのテストを書いてみる

## はじめに
Goでテストコードを書いてみました。

## 足し算と引き算をする関数
“`go
package math

func Add(a, b int) int {
return a + b
}

func Sub(a, b int) int {
return a – b
}
“`

## テストコード

1つずつの条件でも書けるし、テーブルドリブンテストで複数条件を構造体に定義して、ループで回すことでテストを分かりやすく書くことができる。

“`go
package math_test

import (
“testing”

“example/math”
)

func TestAdd(t *testing.T) {
want := 3
if got := Add(1, 2); got != 3 {
t.Errorf(“want %d but got %d”, want, got)
}
}

func TestSub(t *testing.T) {
// テーブルドリブンテスト
tests := []struct {
name string

元記事を表示

【Go】地味に嬉しい整形ライブラリ – pretty

# はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。(同担OKです😉)

今回は複雑な構造体や、ログなどを見やすく整形してくれるGoのライブラリである**pretty**をご紹介します!

# prettyの魅力
こちらの [The Go Playground](https://go.dev/play/p/IiwoGJ79IOb) でも体験できるように、`pretty.Formatter()`を使うことで整形された結果を確認することが出来ます!

“` main.go
package main

import (
“fmt”

“github.com/kr/pretty”
)

func main() {
type myType struct {
a, b int
}
var x = []myType{{1, 2}, {3, 4}, {5, 6}}
fmt.Printf(“%# v\n”, x)
fmt.Printf(“%# v”, pretty.Formatter(x))
}
“`

“` zsh
[]main.myType{main.myType

元記事を表示

Goのプロジェクト構成とパッケージ

# プロジェクト構成

Goでは1つのプロジェクトのレイアウトがある。

https://github.com/golang-standards/project-layout/blob/master/README_ja.md

ただし、このレイアウトを使わないといけないという規制はない。

また、以下のGo moduleのドキュメントも参考になる。

https://go.dev/doc/modules/layout

## project-layoutの主なディレクトリ

以下は、[project-layout](https://github.com/golang-standards/project-layout/blob/master/README_ja.md) のレイアウトの主なディレクトリ。

:::note warn
project-layout は、Go公式のレイアウトではないので、必ずしも守らないといけない規約ではない。
:::

* /cmd : アプリケーションごとにコマンドのmain.goを置く
* /internal : 外部に公開したくないプライベートなコードを

元記事を表示

GoとReact+TypeScriptで筋トレメニュー表を作ろう!

## はじめに
初めましての人もそうでない人もこんにちは!

最近暑くなりすぎて我が家の冷凍庫がアイスの箱で埋め尽くされています!

毎日のようにアイスを食べていたらあらびっくり!
体重がめちゃんこ増えてました!

こんなだらしない体では恥ずかしくて海水浴に行けません!(漢心ピ〜ンチ♂)
かなりやばいのでそろそろ筋トレを始める時期だと思っています!

どうせならプログラミングを駆使して筋トレメニュー表を作ることで技術力向上と夢のマッスルボディの両方を鍛えたいです!

そこで今回は筋トレメニュー表をGoとReactを使って作ってみました!
ぜひ最後までご覧ください!

## 今回使う技術
### フロントエンド
React + TypeScript ・ Css

### バックエンド
Go

## 準備をしよう!
“`
kintore
├─ backend
| └─ main.go
├─ frontend
| └─ src
| └─ App.tsx
| └─ App.css
├─ ・・・
・・・
“`

今回主に使うディレクトリ構成としてはこんな感じです!

まず

元記事を表示

Go言語におけるnilの構造体ポインタの扱い方:フィールドとメソッドのアクセス

Go言語では、`nil` の構造体ポインタにアクセスする際には注意が必要です。
特に、フィールドとメソッドにアクセスする場合の動作は異なるため、それぞれのケースについて詳しく解説します。

## フィールドにアクセスする場合

`nil` の構造体ポインタに対してフィールドにアクセスしようとすると、ランタイムパニックが発生します。

“`go
package main

import “fmt”

type Foo struct {
Name string
}

func main() {
var foo *Foo
fmt.Println(foo.Name) // panic: runtime error: invalid memory address or nil pointer dereference
}

“`

このコードを実行すると `foo` が `nil` であるため、フィールド `Name` にアクセスしようとする際にランタイムパニックが発生します。
このような場合、フィールドにアクセスする前にポインタが `nil` でないことを確認する必要があります。

元記事を表示

learn-go-with-tests スタブ・モック

# スタブ・モック
3からカウントダウンするプログラムを作成するように求められました。各数値を新しい行に表示します(1秒の間隔を置いて)、ゼロに達すると「Go!」と表示します。そして終了します。

“`
3
2
1
Go!
“`

これに取り組むには、Countdownという関数を作成します。この関数をmainプログラム内に配置して、次のようにします。
“`
package main

func main() {
Countdown()
“`
これはかなり簡単なプログラムですが、完全にテストするには、いつものように反復的、テストドリブンのアプローチを取る必要があります。反復とは、できる限り小さなステップを踏んでいることを確認することです。要件をできる限り小さくスライスして、動作するソフトウェアを使用できるようにすることは重要なスキルです。

作業を分割して反復する方法は次のとおりです。

– 表示 3
– 3、2、1 を表示してGo!
– 各行の間で1秒待ちます

## 最初にテストを書く
“`
func TestCountdown(t *testing.T) {

元記事を表示

go言語 メモリ領域

# メモリ領域
Go言語でどのメモリが使用されるのか残しておきたかったので、その記録です。
“`
[低アドレス]
+——————+ 0x00000000
| ブートローダー      | BIOS/UEFIによって最初に実行されるコード
+——————+ 例: 0x00080000
| カーネル | オペレーティングシステムの中心部分
+——————+ 例: 0x00100000
| スタティック初期化領域 |
+——————+ 例: 0x00200000
| *テキスト領域     | プログラムのコード(命令)
+——————+ 例: 0x00400000
| *データ領域    | グローバル変数、静的変数
+——————+ 例: 0x10000000
| バッファ領域      | I/O操作のための一時データ保存
+——————+ 例: 0x200

元記事を表示

[Go / Echo] Middleware におけるエラーハンドリング時の注意点

## 前段
ミドルウェアのエラーログハンドリング周りの処理が複雑で、いくつか問題が発生していました。
その対処を行う過程で自分が得た知見を簡単にご紹介します。

## ミドルウェアの処理順序
まず Echo の Middleware における注意点は、その処理順序です。

仮に、A・B という Middleware があったとします。
それを、下記のように順に呼び出します。

“`
echo := echo.New()
echo.Use(echo.MiddlewareFunc(middlewares.NewA()))
echo.Use(echo.MiddlewareFunc(middlewares.NewB()))
“`
そして、上記 A・B のそれぞれの Middleware の中では下記のように処理しているとします。
“`
func NewA() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context)

元記事を表示

【初LT登壇】「sqlxからpgxへの移行を今はしない判断をするまで」の深堀りをしてみます!

こんにちは。

株式会社HRBrainでバックエンドエンジニアをしているみつです!

この春に新卒として入社し、さまざまな経験を積む中で、「**sqlライブラリの移行**」というタスクに立ち向かう機会がありました。

[**2024.05.20にししとうLT**](https://4410.connpass.com/event/316005/)では、時間の都合上話せなかった詳細について、この記事で補足したいと思います:relaxed:

(ちなみに、ししとうLTは私にとって人生初のLT登壇でした:joy: 記事執筆時点では、社外LTに聞く側でしか参加したことがないので、もし誘っていただけたら嬉しいですw)

– [資料はこちら ▼](#資料はこちら-)
– [`sqlx`から`pgx`への移行までの話](#sqlxからpgxへの移行までの話)
– [出したかったログの種類:writing\_hand:](#出したかったログの種類writing_hand)
– [色々なGoのSQLライブラリを検討:sunny:](#色々なgoのsqlライブラリを検討sunny)
– [`pq`につい

元記事を表示

依存性逆転の原則をGolangを用いて解説(SOLID原則)

## 目次
– [背景](#背景)
– [依存性逆転の原則(DIP)とは](#依存性逆転の原則dipとは)
– [コードを用いた説明](#コードを用いた説明golangでのmodel-view-controllerのケース)
– [従来の構成](#従来の構成)
– [依存性逆転(DIP)構成](#依存性逆転dip構成)
– [まとめ](#まとめ)
– [参考URL](#参考url)

## 背景
インターフェースの意義を調べていく中でSOLID、依存性逆転の原則について理解する必要があったため、これらの調査内容をまとめる。

## 依存性逆転の原則(DIP)とは

[SOLID](https://ja.wikipedia.org/wiki/SOLID)(オブジェクト指向に用いられる原則)の頭文字
S 単一責任の原則 (single-responsibility principle)
O 開放閉鎖の原則(open/closed principle)
L リスコフの置換原則(Liskov substitution principle)
I インターフェース分離の原則 (in

元記事を表示

golangci-lintを使ってみる

## はじめに
goでプログラミングした際に、文法間違いやエラーチェックが抜けている箇所を指摘してくれるgolangci-lintを使ってみます。

## golangci-lint インストール
“`zsh
brew install golangci-lint
brew upgrade golangci-lint
“`

## Goを書く
“`go
package main

import (
“net/http”
)

func middleware1(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(“before middleware\n”))
next.ServeHTTP(w, r)
})
}

func middleware2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.

元記事を表示

Goのnet/httpで、ミドルウェアを書いてみる

## はじめに
Goの標準パッケージを使ったプログラミングに慣れるために、net/httpだけでミドルウェアを書いてみました。

next.ServeHTTP(w, r)の前に書くか、後に書くかで、いつ処理されるかが決まるようです。

“`go
package main

import (
“net/http”
)

func middleware1(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(“before middleware\n”))
next.ServeHTTP(w, r)
})
}

func middleware2(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r

元記事を表示

Amazon Linux 2023にGolangをインストールする

# はじめに
英語に拒否反応持ってしまう人も多いと思いますので、自分のインストール方法をここに記載しておきます。
2024/7/1時点、現在のバージョンは`go1.22.4`です。
対象OSはAmazonlinux2023を想定しています

## 1.バイナリのダウンロード
“`bash
wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz
“`
## 2.rootユーザにスイッチ
“`bash
sudo su
“`
## 3.不要なディレクトリ削除、バイナリ解凍、配置
“`bash
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.4.linux-amd64.tar.gz
“`
※rootで実行すること

## 4.rootユーザの終了
“`
exit
“`
## 5.パスを通す(bashrcに追記)
公式だと、.profileに記載するようありますが、
個人で使うだけなのでユーザで良いという判断です。
“`bash
vim ~/.bashrc
“`
.ba

元記事を表示

GORMでPostgresのjsonb型を扱う

GORMでPostgresのjsonb型をシンプルな実装で扱う方法についてご紹介します。

# Postgresのjsonb型
PostgresではJSONを扱うデータ型としてjson型の他にjsonb型が用意されています。jsonb型の方が下記の通り、公式でも利用が推奨されていてデータ取得時のパフォーマンスが良くなるなどのメリットが有るようです。

https://www.postgresql.jp/document/16/html/datatype-json.html

> json型とjsonb型というデータ型は、ほとんど 同一の入力値セットを受け入れます。 現実的に主要な違いは効率です。 jsonデータ型は入力テキストの正確なコピーで格納し、処理関数を実行するたびに再解析する必要があります。 jsonbデータ型では、分解されたバイナリ形式で格納されます。 格納するときには変換のオーバーヘッドのため少し遅くなりますが、処理するときには、全く再解析が必要とされないので大幅に高速化されます。 また jsonb型の重要な利点はインデックスをサポートしていることです。

> 一般的に、ほ

元記事を表示

learn-go-with-tests マップ

# マップ
配列とスライスでは、値を順番に格納する方法を見ました。 では、keyでアイテムを保存し、すばやく検索する方法を見てみましょう。

マップを使用すると、辞書と同じようにアイテムを保存できます。 keyは単語、valueは定義と考えることができます。 そして、独自の辞書を構築するよりも、マップについて学ぶより良い方法は何でしょうか?

まず、辞書に定義された単語がすでにあると仮定すると、単語を検索すると、その単語の定義が返されます。

## 最初にテストを書く
まずテストを書きます。実行すると当然パスしません。
`./dictionary_test.go:8:12: undefined: Search`

“`dictionary_test.go
package main

import “testing”

func TestSearch(t *testing.T) {
dictionary := map[string]string{“test”: “this is just a test”}

got := Search(dictionary, “test

元記事を表示

GoのSliceとMapをforループで回すときのnilの扱いを動かしながら調べた

Goのfor rangeでSliceやMapをループ処理を行うことがたくさんあると思います。

rangeの対象のlengthが0やnilの場合、どのような挙動をするのかが気になったのでサンプルコードを書いて動かしてみました。

## Slice

釈迦に説法かもですが、Sliceとは可変長の配列のことで全ての要素の型は同じです。

“`go
ints := []int{1, 2, 3, 4, 5}
fmt.Println(“[]int{1, 2, 3, 4, 5}のlen:”, len(ints))
fmt.Println(“[]int{1, 2, 3, 4, 5}のrange”)
for i, v := range ints {
fmt.Println(i, v)
}
“`

こんなコードを書いたときにlenは5、for文は5回繰り返します。

アウトプットは以下のようになります。

“`
[]int{1, 2, 3, 4, 5}のlen: 5
[]int{1, 2, 3, 4, 5}のrange
0 1
1 2
2 3
3 4
4 5
“`

次からSli

元記事を表示

OTHERカテゴリの最新記事