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

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

【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() {

元記事を表示

【Go言語】stringsパッケージとbytesパッケージ

# 文字列の連結

Goには文字列を連結する方法は2通りある。

## シンプルな連結(`+=`で連結する)

スライスの全ての文字列を連結する`concat`関数を作成する。

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

“`go
func concat(values []string) string {
s := “”
for _, value := range values {
s += value
}
return s
}
“`

これだと反復ごとに`s`は更新されず、新たな文字列がメモリから再割り当てされる。

## strings.Builderを使用する方法(事前割り当てなし)

stringsパッケージのBuilderを用いることで上記の問題が解決し、メモリ上のコピーを最小限にする。

“`go
func concat(values []string) string {
sb := strings.Builder{}
for _, value := ra

元記事を表示

Go言語でAmazonの商品検索を行う。

# やりたいこと

Go言語の勉強の一環として、Amazonの商品検索結果を取得するプログラミングを作成する。

# 環境

* Windows 11 Pro
* Go バージョン 1.22.4

# 事前準備

## アクセスキーとシークレットキーの取得

AmazonアソシエイトのAmazon Product Advertising API(PA-API)にアプリケーションを登録し、アクセスキーとシークレットキーを取得する。

https://affiliate.amazon.co.jp/

![スクリーンショット 2024-07-15 101513.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/e28e7417-171b-f7bc-2412-912f08d53b78.png)

## pa-apiモジュールの取得

github.com/goark/pa-apiからモジュールを取得する

“`powershell
go mod init pa-api
go get github.c

元記事を表示

【gomonkey】インライン化された関数にはモンキーパッチが効かない

# TL; DR

– コンパイラの最適化によって `gomonkey.ApplyFunc` が効かなくなることがある
– `-gcflags=all=-l` で最適化を無視することでテスト可能

https://github.com/agiledragon/gomonkey/issues/34

# はじめに
gomonkey は、関数をモンキーパッチすることができるモジュールです。ユニットテストでHTTP通信/DBアクセス関数等をモックに差し替えることで、再現しづらいコーナーケースもテストできるようになります。

https://github.com/agiledragon/gomonkey

:::note alert
モンキーパッチではunsafeを用いたメモリ書き換えを行っています。**プロダクトコード側への使用は非推奨です**。
:::

本記事では、モンキーパッチの関数 `ApplyFunc` が動作しなかった際の原因と対処法について紹介します。

# gomonkey.ApplyFunc
`ApplyFunc` を使用すると、引数に渡した関数の処理を書き換えることができ

元記事を表示

【Go言語】Trim関数

# Trim関数とは?

[strings](https://pkg.go.dev/strings)パッケージの[TrimLeft](https://pkg.go.dev/strings#TrimLeft)、[TrimPrefix](https://pkg.go.dev/strings#TrimPrefix)などのTrimXXXとなる関数のこと。

特に、TrimRight と Trimsuffixを混同してしまいがちなので、解説していきます。

# TrimRight

`TrimRight`は、末尾の文字が、第二引数に指定したルーンの集合に当てはまったら、その文字を削除します。

“`go
fmt.Println(strings.TrimRight(“123oxo”, “xo”)) // 123
“`

`123o`になりそうですが、oは`xo`の一部なので、削除されて123となります。

# TrimSuffix

TrimSuffixは、与えられた接尾辞の文字列を末尾から取り除いた値を返します。

“`go
fmt.Println(strings.TrimSuffix(“

元記事を表示

Goのfor文について

## Go言語のfor文の使い方と注意点
Go言語には、一連のステートメントを繰り返すための強力な制御構文であるfor文があります。この記事では、for文の基本的な使い方から、for-range文、無限ループ、そして注意点について詳しく解説します。
## 基本的なfor文の使い方
for文は、初期化、条件式、後続処理の3つの部分から構成されます。以下は基本的なfor文の構文です。
“`go:goファイル
for i := 0; i < 10; i++ { fmt.Println(i) } ``` ```:結果 0 1 2 3 4 5 6 7 8 9 ``` ### 条件式のみのfor文 他の言語のwhileループに似た形式で、条件式のみを使ったfor文も可能です。 ```go:goファイル i := 0 for i < 10 { fmt.Println(i) i++ } ``` この記法でも0から9までを出力します。 ### 無限ループ 無限ループは、条件式を書かずにforを使用することで実現できます。システムの監視やユーザーの入力待ちなどに使われます。 ``

元記事を表示

Go言語のジェネリクス

## Go言語のジェネリクスの使い方とその利点
Go言語は静的型付けプログラミング言語であり、型安全性を保ちながら効率的なコードを書くことができます。Go 1.18で導入されたジェネリクスは、異なるデータ型に対して再利用可能な関数やデータ構造を作成するための強力な機能です。この記事では、ジェネリクスの基本的な使い方とその利点について説明します。
## ジェネリクスとは?
ジェネリクスは、さまざまなデータ型で動作する関数やデータ構造を作成するための機能です。これにより、特定のデータ型に依存しないコードを書くことができます。例えば、整数や浮動小数点数、文字列などを扱う関数を1つのジェネリック関数として定義できます。
## 基本的な使い方
ジェネリクスを使うには、型パラメータを関数や型に追加します。型パラメータは角括弧([])内に定義され、各パラメータは大文字で始まる識別子にします。
例1: 配列の要素の合計を計算する関数
以下の例では、整数と浮動小数点数の配列の合計を計算するジェネリック関数を定義しています。
“`go:例
package main

import (
“fmt”

元記事を表示

個人メモ〜Go言語入門(少し目的のあるコードを書く編)

別記事で基礎的な文法を調べ、Hello Worldまで行った。
[個人メモ〜Go言語入門(文法と環境構築編)](https://qiita.com/PG-practice/items/42f17aa2ad43e473b033)

今回の記事ではHello Worldの次のステップとして少しコードを書いてみた。
以下を順に見ていく。
– 同一パッケージ内で複数のファイルを作成する
– 別のパッケージを作成する
– HTTPリクエスト
– AWS SDK for Go V2をインストールして、Lambda関数を呼び出す

この記事でやることを理解するために調べた内容が上記の記事にメモってあるので、この記事の内容は基本的に上記記事も見ればわかるはず。

## 前提
環境構築してhello worldまでできている。
`go mod init hello` している。
“`:go.mod
module hello

go 1.22.5
“`

## 同一パッケージ内で複数のファイルを作成する
以下の構成で、`hello.go`から`hello2.go`のメソッドを呼び出す。

構成
`

元記事を表示

Golangのスライスについて

# Golangのスライスについて
Golang(Go言語)では、スライスは非常に重要なデータ構造です。スライスは、配列の一部を参照する柔軟で強力な方法を提供します。この記事では、スライスの基本的な使い方とその特性について説明します。
## スライスの基本
スライスは、配列の一部を参照するためのデータ構造です。スライスは、配列の要素へのポインタ、長さ、および容量を持っています。以下は、スライスの基本的な宣言と使用方法です。
“`go:例
package main

import “fmt”

func main() {
// 配列を作成
arr := [5]int{1, 2, 3, 4, 5}

// スライスを作成
slice := arr[1:4]

fmt.Println(“配列:”, arr)
fmt.Println(“スライス:”, slice)
}
“`
“`:結果
配列: [1 2 3 4 5]
スライス: [2 3 4]
“`
このコードでは、arrという配列からsliceというスライスを作成しています。スライスは

元記事を表示

Goの公式ブログをただ翻訳しただけ

# セキュアなランダム性 in Go 1.22
コンピュータはランダムではありません。むしろ、ハードウェア設計者は、コンピュータが毎回同じ方法でプログラムを実行するように非常に努力しています。そのため、プログラムがランダムな数値を必要とする場合、それには追加の努力が必要です。伝統的に、コンピュータ科学者やプログラミング言語は、統計的ランダム性と暗号的ランダム性という2つの異なる種類のランダム数を区別してきました。Goでは、それらはそれぞれ `math/rand` と `crypto/rand` によって提供されています。この投稿では、Go 1.22がこれら2つをどのように近づけたかについて説明します。具体的には、`math/rand(および前回の投稿で言及した math/rand/v2)`で暗号的ランダム数のソースを使用することにより、より良いランダム性を実現し、開発者が誤って `math/rand` を使用した場合の被害を大幅に減らすことができました。
Go 1.22が何をしたのかを説明する前に、統計的ランダム性と暗号的ランダム性の違いを詳しく見てみましょう。
## 統計的ランダム性

元記事を表示

個人メモ〜Go言語入門(文法と環境構築編)

機会があってGoに入門してみた。Goはシンプルで機能が少ないらしいので、基本的なことを抑えればある程度読めそうと期待。
この記事で書くのは以下の二つ。

– Hello World
環境構築まではやる。それ以外に多少目的あるコード書くのもやった。それは別記事に分ける。[個人メモ〜Go言語入門(少し目的のあるコードを書く編)](https://qiita.com/PG-practice/items/7dbfc617f7d627a8c736)
– 文法についてメモ
自分が概念を思い出せるように書くだけ。for文とかは調べればすぐ出てくるので、へぇと思ったところだけ。ゴルーチンのところはサンプルを動かしつつ。

# 環境構築
OS: Ubuntu 24.04 LTS

コマンドやバージョンは公式から。
https://go.dev/dl/
https://go.dev/doc/install

以下を実行
“`bash
curl -OL https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
rm -rf /usr/local/go && sudo ta

元記事を表示

【Go】名前付き戻り値を使うべきなのか

# ブランクreturnの挙動
名前付き戻り値は以下のようにブランクreturnを使用することができる。
“`go:
package main

import “fmt”

func add(num1, num2 int) (addResult int) {
addResult = num1 + num2;
return
}

func main() {
fmt.Println(add(1, 2)) //3
}
“`

ではブランクreturnに誤って引き算の計算結果を記述した際の動作はどうなるのだろうか。
“`go:
package main

import “fmt”

func add(num1, num2 int) (addResult int) {
addResult = num1 + num2;
return num1 – num2
}

func main() {
fmt.Println(add(1, 2)) // -1
}
“`
addメソッドは-1を返してしまうようだ。名前付き戻り値はreturnに値を記述した時はその値を返してしまうようだ。

元記事を表示

Goのエラーハンドリングざっくり

## GO言語のエラーハンドリング
GO言語では、エラーを示すために組み込みの`error`型を使用します。例えば、os.Open関数はファイルを開く際に失敗すると非nilの`error`値を返します。
“`go:例
f, err := os.Open(“filename.ext”)
if err != nil {
log.Fatal(err)
}
// ファイルを開いた後の処理
“`
#### `error`型の詳細
`error`型はインターフェース型であり、以下のように定義されています。
“`go:例
type error interface {
Error() string
}
“`
最も一般的な`error`の実装は、`errors`パッケージの`errorString`型です。

“`go:例
type errorString struct {
s string
}

func (e *errorString) Error() string {
return e.s
}
“`
`errors.New`関数を使用して`errorSt

元記事を表示

Goのregexpとregexp2のパッケージの違い

## regexp パッケージ
regexpはGoの標準ライブラリに含まれている正規表現パッケージです。以下はその主な特徴です:
特徴
#### 1. シンプルで高速:
– regexpはシンプルで高速な正規表現エンジンを提供します。
– 基本的な正規表現機能をサポートしています。
#### 2. RE2エンジン:
– regexpはGoogleのRE2エンジンをベースにしており、バックトラッキングをサポートしないため、常に線形時間で動作します。
– 無限ループやスタックオーバーフローのリスクがありません。
#### 3.基本的な機能:
– 名前付きキャプチャグループや条件付きパターンなどの高度な機能はサポートしていません。
##### 使用例
“`go:例
package main

import (
“fmt”
“regexp”
)

func main() {
pattern := `[a-zA-Z]+`
re := regexp.MustCompile(pattern)
text := “Hello123 World

元記事を表示

Go言語で楽天市場の商品検索を行う。

# やりたいこと

Go言語の勉強の一環として、楽天市場の商品検索結果を取得するプログラミングを作成する。

# 環境

* Windows 11 Pro
* Go バージョン 1.22.4

# 事前準備

Rukutenデベロッパーズにアプリケーションを登録し、アプリIDとアプリケーションシークレットを取得する。
(アプリケーションシークレットは使わないが、再発行できないので忘れずに保存すること。)

https://webservice.rakuten.co.jp/documentation/ichiba-item-search

![スクリーンショット 2024-07-11 090033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/d5888cc2-30d8-97d1-8110-2f9cc194b6cd.png)

# コード

“`main.go
package main

import (
“context”
“encoding/json”
“fmt”
“io”

元記事を表示

Go言語の正規表現ライブラリ「regexp2」

## 概要
regexp2は、Go言語で使用される正規表現ライブラリであり、.NETの正規表現エンジンをベースにしています。regexp2は、Goの標準ライブラリのregexpパッケージに比べて、より強力な正規表現機能を提供します。特に、バックトラッキングや名前付きキャプチャグループなどの高度な機能をサポートしています。

## インストール
regexp2を使用するには、まずGoモジュールをインストールする必要があります。以下のコマンドを実行してインストールします
“`shell:コマンド
go get github.com/dlclark/regexp2
“`
## 基本的な使い方
以下に、`regexp2`を使用して正規表現を扱う基本的な方法を示します。
#### 1. 正規表現のコンパイル
正規表現を使用する前に、まず正規表現パターンをコンパイルする必要があります。`regexp2.Compile`関数を使用して正規表現パターンをコンパイルします。
“`go:例
package main

import (
“fmt”
“github.com/dlclar

元記事を表示

Go言語の正規表現

## 基本的な使い方
Go言語のregexpパッケージを使用して、正規表現を扱う基本的な方法を以下に示します。
1. 正規表現のコンパイル
正規表現を使用する前に、まず正規表現パターンをコンパイルする必要があります。***regexp.Compile関数***を使用して正規表現パターンをコンパイルします。
“`go:例
package main

import (
“fmt”
“regexp”
)

func main() {
pattern := `[a-zA-Z]+`
re, err := regexp.Compile(pattern)
if err != nil {
fmt.Println(“Error compiling regex:”, err)
return
}
fmt.Println(“Regex compiled successfully:”, re)
}
“`
“`:結果
Regex compiled successfully: [a-zA-Z]+
“`
2. パターンマッ

元記事を表示

【Go言語】文字列とrune

# 文字列

Goの文字列はイミュータブルなデータ構造

* イミュータブルなバイト列へのポインタ
* そのバイト列内のバイトの総数

# rune

* 文字セット : 文字の集合。Unicodeの文字セットは $ 2^{21} $個ある
* エンコーディング : 文字のリストを2進数で翻訳したもの。UTF-8は全てのUnicode文字を可変なバイト数(1~4byte)でエンコーディングできるエンコーディング規格

code pointとは、unicodeで1つの値で表される項目を指す。「漢」は、U+6f22コードポイントで識別される。UTF-8では、「漢」は0xE6, 0xBC, 0xACの3バイトでエンコードされる。runeはUnicodeのコードポイントである。
Unicodeのコードポイントは21ビットで、コードポイントを保持するためのruneはint32のエイリアスとなる。

“`go
type rune = int 32
“`

以下は文字リテラル(文字列定数)を代入している。

“`go
s := “hello”
“`

Goでは、ソースコードはUTF-8でエン

元記事を表示

gRPCのコアコンセプト、アーキテクチャ、およびライフサイクル

## gRPCのコアコンセプト、アーキテクチャ、およびライフサイクル
gRPCは、異なるマシン上のサーバーアプリケーションのメソッドを、ローカルオブジェクトのように直接呼び出すことができるリモートプロシージャコール(RPC)システムです。このガイドでは、gRPCの主要なコンセプト、アーキテクチャ、およびRPCライフサイクルについて説明します。
### 概要
#### サービス定義
多くのRPCシステムと同様に、gRPCはサービスを定義し、リモートで呼び出すことができるメソッドとそのパラメータおよび戻り値の型を指定するという考えに基づいています。デフォルトでは、gRPCはプロトコルバッファをインターフェース定義言語(IDL)として使用して、サービスインターフェースとペイロードメッセージの構造を記述します。必要に応じて他の代替手段を使用することも可能です。
以下は、サービス定義の例です
“`proto:greeter.proto
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}

元記事を表示

【Go】スタックとヒープについて簡単なサンプルで確認する

## はじめに
メモリ領域にはスタックとヒープがあります。
スタックは関数呼び出しやその中で使われるローカル変数などが格納されるメモリ領域。
ヒープは動的にメモリが割り当てられる領域で、サイズの決まっていないデータや関数外で参照されたりする場合に使用するメモリ領域。

ヒープが大量に使用されてしまうと処理動作が遅くなるため、パフォーマンス改善をしていく際にこれらの知識が必要そうだったので、サンプルコードで確認したいと思います。

## コード
“`go
package main

// スタック上に割り当て
func stackExample() int {
x := 42
y := x + 1
return y
}

// ヒープ上に割り当て
func heapExample() *int {
z := 42
return &z
}

func main() {
_ = stackExample()

_ = heapExample()
}
“`

## 動かしてみる
コンパイルする際に、-gcflags -mをつけると、エスケープ解析のログを出力することができます

元記事を表示

OTHERカテゴリの最新記事