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

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

【Go】zapで出力するログのタイムスタンプをJSTにする

# 環境

`go.uber.org/zap v1.25.0`

# やりたいこと

デフォルトで、`”ts”:1720662061.1188495` となっている部分を JST(e.g. `”2024-07-11T12:56:52+09:00″`) で出したい。

“`
{“level”:”info”,”ts”:1720662061.1188495,”caller”:”xxx”,”msg”:”xxx”}
“`

# コード

> package config は環境により異なります。

“`go
package config

import (
“os”
“time”

“go.uber.org/zap”
“go.uber.org/zap/zapcore”
)

func ZapConfig(app *newrelic.Application) *zap.Logger {
core := createZapCore()

return zap.New(
core,
zap.AddCaller(),
zap.AddStacktrace(zapcore.E

元記事を表示

【Go】delveでデバッグしてみる

## はじめに
Goでデバッグってどうやってやるんだろうと思ったので、調べてやってみました。

## delve インストール
“`zsh
go install github.com/go-delve/delve/cmd/dlv@latest
“`

## VSCode拡張機能 インストール
https://marketplace.visualstudio.com/items?itemName=golang.Go

## 動かしてみる
ブレークポイントを置く
![スクリーンショット 2024-07-11 12.17.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603224/b888b8f7-45fd-d302-b34c-2bc082369c14.png)

## デバッグを実行
デバッグタブの「実行とデバッグ」をクリック
![スクリーンショット 2024-07-11 12.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazo

元記事を表示

【Go】公式ツール “eg” を使って効率的にGoのコードをリファクタリングする

# はじめに

こんにちは、ken です。お仕事では Go をよく書きます。
最近、Go の公式パッケージである`golang.org/x/tools`を眺めていたら、なにやら有用そうなパッケージを見つけたので今回はそれについて書こうと思います。
それは**eg**というリファクタリングツールです。

https://pkg.go.dev/golang.org/x/tools/cmd/eg

# eg とは

eg は、**例ベースで Go コードをリファクタリングするためのツール**です。このツールを使用することで、特定のコードパターンを別のコードに置き換えることができ、効率的にリファクタリングが行えます。

先ほど貼った公式ドキュメントに詳しい説明があるかと思いきや

> The eg command performs example-based refactoring. For documentation, run the command, or see Help in golang.org/x/tools/refactor/eg.

としか書かれてませんでした…(なんでや.

元記事を表示

【Go言語】オーバーフローの仕組みと検出

# オーバーフロー

Goには整数型が10個ある。

* 符号付き整数型 : int, int8, int16, int32, int64
* 符号なし整数型 : uint, uint8, uint16, uint32, uint64

32bitシステムの場合は32bitのint32, 64bitシステムの場合は64bitのint64を使う。
ここで、int32の最大値(`math.MaxInt32`)に1を足して、出力させてみます。

“`go
func main() {
var counter int32 = math.MaxInt32
fmt.Printf(“counter = %d\n”, counter)
counter++
fmt.Printf(“counter = %d\n”, counter)
}
“`

このコードは、コンパイルエラーやパニックは起きませんが、オーバーフローが発生します。実行すると、以下のようになります。

“`txt:実行結果
counter = 2147483647
counter = -2147483648
“`

int8での

元記事を表示

マルチステージビルドとdistrolessイメージを活用してGoイメージを極限まで軽量化する

**マルチステージビルド** は,Dockerイメージのビルドを複数のステージに分割する機能です.Goのソースコードをビルドするステージと実行時のステージを分離することで,実行時のイメージサイズを軽減できます

実行時のイメージには **Alpine** のような軽量Linuxが使われることが多いですが,[distrolessイメージ](https://github.com/GoogleContainerTools/distroless)も良く知られています.distrolessイメージは,Debianイメージに含まれるファイルを極限まで削減したもので,シェルすら含まれていません.

> Distroless images are very small. The smallest distroless image, gcr.io/distroless/static-debian11, is around 2 MiB. That’s about 50% of the size of alpine (~5 MiB), and less than 2% of the size of debi

元記事を表示

Go言語のstructを理解したい

## はじめに
こんにちは、皆さん!今回は、Go言語の重要なデータ構造である`struct`について学んでいきましょう。`struct`は、複数のフィールドを持つデータ型を定義するために使用されます。オブジェクト指向プログラミングのクラスに似ていますが、Go言語ではシンプルで効率的な方法でデータを扱うことができます。

## structの基本

まずは、`struct`の基本的な定義方法を見てみましょう。
“`go:例
package main

import “fmt”

// Personという名前のstructを定義
type Person struct {
Name string
Age int
}

func main() {
// Person型の変数を作成
p := Person{Name: “Alice”, Age: 30}
fmt.Println(p)
}
“`
“`:結果
{Alice 30}
“`

この例では、`Person`という名前の`struct`を定義し、`Name`と`Age`という2つのフィールドを

元記事を表示

Go言語の遅延実行(defer)を理解したい

## deferとは?
deferキーワードは、関数の終了時に実行される関数呼び出しを指定するために使用されます。deferを使うことで、リソースの解放やクリーンアップ処理を簡潔に記述することができます。
### 基本的な使い方
以下は、deferの基本的な使い方の例です。

“`go:例
package main

import “fmt”

func main() {
fmt.Println(“start”)
defer fmt.Println(“deferred”)
fmt.Println(“end”)
}
“`
このプログラムの出力は以下のようになります。
“`結果:結果
start
end
deferred
“`
deferを使った関数呼び出しは、main関数の終了時に実行されるため、endの後にdeferredが出力されます。
## deferの利点
#### 1. リソースの解放
deferは、ファイルやデータベース接続などのリソースを確実に解放するために使用されます。以下は、ファイルを開いて読み取る例です。
“`go:例
package

元記事を表示

Goroutineを理解したい!

## Goroutineとは?Go言語の並行処理を理解しよう
Go言語(Golang)は、Googleによって開発されたオープンソースのプログラミング言語で、シンプルで効率的な並行処理をサポートしています。その中でも特に注目すべき機能が「Goroutine」です。この記事では、Goroutineの基本概念、使い方、そしてその利点について詳しく解説します。
## Goroutineとは
Goroutineは、Go言語における軽量なスレッドのようなものです。Goroutineを使うことで、プログラムの複数の部分を同時に実行することができます。Goroutineは非常に軽量で、数千から数百万のGoroutineを同時に実行することが可能です。

#### Goroutineの特徴
1. メモリ消費:
Goroutineはカーネルスレッドに比べて非常に少ないメモリしか消費しません。カーネルスレッドは1MB程度のスタックを必要としますが、Goroutineは2KBのスタックだけが必要です。
2. 生成・破壊コスト:
GoroutineはGoランタイムから生成と破壊が行われるため、コストが低いです

元記事を表示

【Go】ファイル操作

# はじめに
今回はGo言語でのファイルの読み書きの方法を今回はまとめてみました。

# ファイルをオープンして書き込む
まず、一般的なファイルを開いて書き込む方法についてです。
以下は、読み書きを2種類の方法で行っています。data1とdata2というファイル名で中にHello World!と書き込むコードです。

:::note info
蛇足ですが、Go1.16以降ではioutilパッケージのいくつかの関数が推奨されなくなり、osパッケージに移動されています。今回のWriteFileとReadFileも元々はioutilの関数でしたが使おうとすると警告が出ます。
:::

“`go
package main

import (
“fmt”
“os”
)

func main() {
data := []byte(“Hello World!\n”)
err := os.WriteFile(“data1”, data, 0644)
if err != nil {
panic(err)
}
read1, _ := os.ReadFile(“data1”)
fmt.

元記事を表示

Goの型変換の正体

## はじめに
42Tokyoに入ってGo言語を触りだして少し経ちますが、Go言語の仕様そのものについて気になる部分がありました。
Go言語にはパッケージに定義されている関数とは異なり、builtinと呼ばれる組み込み関数群があります。例を挙げると、len()やappend()、panic()などがこれにあたります。
さて、Go言語には型変換と呼ばれる仕組みがあります。
“`go
var i int = 42
var f float64 = float64(i)
“`
このコードは、int型の42をfloat64に変換しています。このfloat64は一体何の関数かが気になり、今回これを調べることにしました。

## builtin.goを読む

https://github.com/golang/go/blob/master/src/builtin/builtin.go

Go言語の組み込み関数は、builtinパッケージのbuiltin.goに記載されています。
コードそのものが書かれているわけではなく、ここには事前に宣言された定数や変数、型などが記載されています。
builti

元記事を表示

【Go】クッキー

# はじめに
前回、レスポンスについてまとめたのですが、長くなるためクッキーは割愛しました。
そこで今回はサーバーからHTTPレスポンスメッセージを通して送られる`クッキー`についてまとめます。

https://qiita.com/YokoYokoko/items/b62f994a5d79da362aed

# クッキー
クッキーは、サーバーがクライアントに送信し、クライアント側で保存される情報の小さな断片です。例えば、ブラウザ(Chrome)で検証すれば簡単に確認できます。(下の画像は何も入っていません。)
![スクリーンショット 2024-07-10 11.32.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324306/79d4bb97-963b-c076-facb-5a91d17fb70b.png)

サーバーはステートレスであるため、一度クライアントとのやり取りが終わるとその状態を保持しません。そのため、次のリクエストが来たときにそのクライアントが誰なのかを覚えていません。

例えば

元記事を表示

【Go】レスポンス

# はじめに
前回はリクエストの`*http.Request`に焦点を当てて、どのようにリクエストの中身を読み取るのかについてまとめました。

https://qiita.com/YokoYokoko/items/04afe5ff82a4f73909c3

今回は`http.ResponseWriter`とJSONに焦点を当ててまとめてみたいと思います。

# ResponseWriter
サーバーを立てるときには`http.ResponseWriter`と`*http.Request`を引数とした関数を用意します。

:::note info
余談ですが、http.ResponseWriterはインターフェースなので一見値渡しのように見えますが、実際はresponseの参照渡しです。
:::

ResponseWriterインターフェースには次の3つのメソッドがあります。
| メソッド | 説明 |
| — | — |
| Write | レスポンスボディにデータを書き込みます。引数としてバイトスライスを受け取り、書き込んだバイト数とエラーを返します。 |
| WriteHe

元記事を表示

Go言語でのシャドーイングの理解

## 実装

“`go
func main() {

x := 10
fmt.Println(“outter block”, x)//10

if x > 5 {
fmt.Println(“inner block”, x)//10
x := 5
fmt.Println(“inner block”, x)//5
}
fmt.Println(“outter block”, x)//10
“`

上記のxで変数宣言したものは条件分岐より外では、10になります。ブロック内で再宣言すると値が隠蔽され、5になります。そして、ブロック外では最初に宣言した値にアクセスでき、再び10になります。この性質をシャドーイングと言います。

“`go
func main() {
var x int = 10
fmt.Println(“Outside block:”, x) // 10

{
var x int = 20 // ここで新しい変数を宣言しようとすると、エラーが発生します。
fmt.Println(“Insid

元記事を表示

【Go】リクエスト

#
今読んでいる技術書の内容で大事だと思った部分を少しずつまとめていきたいと思います。

今回読んでいる本はこちら
__Goプログラミング実践入門__

この書籍では、フレームワークに頼らず標準ライブラリでweb開発をすることができます。
個人的にフレームワークはブラックボックスが多すぎて面倒であまり好きではない派なので、これを理解できることで理解が深まるのではないかと考え購入しました。

この本ではプログラミング言語Goとその標準のライブラリだけを使って、
ゼロからWebアプリケーションを開発するのに必要な事柄を解説します。

ほかのライブラリやその他のトピック(Webアプリケーションのテストやデプロイなど)について解説するページもありますが、Go言語の標準ライブラリのみを用いたWeb開発を解説することがこの本の主目的です。

本記事では、リクエストとレスポンスについてまとめています。

# Request
まず、`net/http`パッケージの`http.Request`構造体は以下の通り定義されています。
| フィールド | 説明 |
| — | — |
| `Meth

元記事を表示

GORMで特定のフィールドのみ選択(select)したとき、mapを使用してクエリ結果を取得する方法

# はじめに
GORMを使用してデータベースからデータを取得する際、しばしば特定のフィールドのみを選択したい場合があります。
通常、これはカスタム構造体を定義し、その構造体へスキャンすることでデータを取得しますが、カスタム構造体の定義がめんどくさい場合、簡易的にmapを使用することでも取得が可能です。

“`go
type User struct {
ID uint
Name string
Email string
Age int
}

type Order struct {
ID uint
UserID uint
ProductName string
Quantity int
TotalPrice float64
}

// mapを使用し、ここにスキャンする
var results []map[string]interface{}

// 2つのテーブルをjoinして特定のカラムを選択する
err := db.Table(“users”)

元記事を表示

【Go】Filter, Mapなどの便利関数を手軽に使いたい、そんなあなたへ

# はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。(同担OKです😉)
Goには、標準でFilterやMap、FindやFirstなどの関数が実装されていません。

しかし、ジェネリクスの登場によりこれらの便利な関数を実装できるようになりました。
そこで今回は、ジェネリクスを用いた便利関数がまとめられているライブラリである**samber/lo**をご紹介します😁

# 便利ライブラリ「samber/lo」

https://github.com/samber/lo?tab=readme-ov-file

> ✨ samber/lo is a Lodash-style Go library based on Go 1.18+ Generics.

Go 1.18から登場したジェネリクスを元にしたLodashスタイルのGoライブラリです。
Lodashとは、JavaScriptの便利な関数を提供しているライブラリのことで、samber/loはそのGo版になります。

名前の由来も紹介されており、Lodashのような短い名前かつGoパッケージで使われていないことが挙げられていま

元記事を表示

Goの脆弱性診断を定期実行したい(govulncheck-action)

# はじめに
Goプロジェクトのセキュリティを確保するために、定期的な脆弱性診断は必須ですよね。

Goの脆弱性診断を定期実行する仕組みを構築すれば、開発スピードを落とすことなくセキュリティ対策を強化できます。

今回は、[govulncheck-action](https://github.com/marketplace/actions/golang-govulncheck-action)を使って、Goの脆弱性診断を継続的に実行する方法について紹介します。

# GitHub Actionsのワークフロー作成
以下のyamlを.github/workflows配下に追加します。
“`.github/workflows/go_vluncheck_sample.yaml
name: Go Vulnerability Check
on:
# ここで定期実行のための設定をしています
schedule:
– cron: ‘0 23 * * *’ # UTC表記。毎日8時(JST)に実行
jobs:
go_vulncheck:
runs-on: ubuntu-20.04

元記事を表示

Goの正規表現処理をstringsパッケージで代替してBenchmarkを測ってみる

Goの正規表現を標準の [regexp](https://pkg.go.dev/regexp) パッケージで処理すると遅い、という話をしばしば聞きます。
これは [こちらの記事](https://qiita.com/momotaro98/items/09d0f968d44c7027450d) などで紹介されているように、Goの正規表現で採用しているアルゴリズム(Thompson NFA)の都合上、他のアルゴリズムを採用している言語と比較した時、苦手なケースでは遅くなる、というのが実態のようです。

実際のパフォーマンスは、ユースケースに合わせたBenchmarkテストを書いて測りつつ、他の手法と比較してみるのが良さそうです。
今回は、Go標準の [strings](https://pkg.go.dev/strings) パッケージを使ってどの程度代替できるのか、速くなるのか、いくつかのパターンでBenchmarkを測ってみました。

## 実行環境
go version go1.22.5 darwin/arm64

## 前提
Benchmarkの試行回数は少ないので、計測結果に多

元記事を表示

【Go言語】n進数

## はじめに

“`go
func main() {
sum := 100 + 020
fmt.Println(sum)
}
“`

これを実行すると、**120**ではなく、 **116** が出力されます。
Goでは、0から始まる数字は8進数とみなされます。

:::note info
ちなみに余談ですが、javascriptはもっと奇妙な動作をします。気になる方は
[【超難問】絶対に解けないJavaScriptクイズ8選](https://qiita.com/twrcd1227/items/a64c3f22da46ff2c0fbd)
:::

## 2進数(バイナリ)

`0b`、`0B`のprefixつける。(e.g. 0b1010)

以下はビット演算の例。

“`go
func main() {
var a uint8 = 0b1010
var b uint8 = 0b0110

fmt.Printf(“a AND b = %08b\n”, a & b)
fmt.Printf(“a OR b = %08b\n”, a | b)

元記事を表示

【Go言語】Go100Tips1~4をまとめてみた

# はじめに

Go 100 Tipsの 1〜4 をまとめました。

スライドもあります。

また、Tip.3に関しては、別の記事にしました。

https://qiita.com/twrcd1227/items/6e7079d16fd27a7c7d6e

# シャドーイング

シャドーイングとは、異なるスコープで同じ名前の変数が使用されたときに、異なる変数として扱われること。ちなみに、同じスコープ内だと再宣言となり、コンパイラエラーとなります。

“`go
func main() {
n := 1
if true {
n := 999 // シャドウイングされる
fmt.Println(n) // 999
}
fmt.Println(n) // 1
}
“`

`:=`ではなく、代入演算子`=`を使うとシャドウイングされません。

“`go
var n int
func main() {
n := 1
if true {

元記事を表示

OTHERカテゴリの最新記事