- 1. 【Go】名前戻り値を使うべきなのか
- 2. Goのエラーハンドリングざっくり
- 3. Goのregexpとregexp2のパッケージの違い
- 4. Go言語で楽天市場の商品検索を行う。
- 5. Go言語の正規表現ライブラリ「regexp2」
- 6. Go言語の正規表現
- 7. 【Go言語】文字列とrune
- 8. gRPCのコアコンセプト、アーキテクチャ、およびライフサイクル
- 9. 【Go】スタックとヒープについて簡単なサンプルで確認する
- 10. 【Go言語】浮動小数点
- 11. Go Development Dashboardとは?
- 12. Dify-Sandbox: 安全な分離環境でコードを実行する
- 13. 【Go】for rangeでmapの要素を取り出す順番
- 14. gRPCのクイックスタートを実施してみる!!
- 15. 【Go】ファイルに追記したいときは、os.OpenFileメソッドでos.O_APPENDフラグを使おう
- 16. 【Go】依存性の注入をやってみる
- 17. Go言語のデータ型チートシート
- 18. 【Go】 スライスをコピーした時のメモリの共有
- 19. gRPC入門
- 20. Go言語でYahoo!ショッピングの商品検索を行う。
【Go】名前戻り値を使うべきなのか
# ブランクreturnの挙動
名前付き戻り値は以下のようにブランクreturnを使用することができる。
“`go:
package mainimport “fmt”
func add(num1, num2 int) (addResult int) {
addResult = num1 + num2;
return
}func main() {
fmt.Println(add(1, 2)) //3
}
“`ではブランクreturnに誤って引き算の計算結果を記述した際の動作はどうなるのだろうか。
“`go:
package mainimport “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 mainimport (
“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 mainimport (
“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 mainimport (
“fmt”
“github.com/dlclar
Go言語の正規表現
## 基本的な使い方
Go言語のregexpパッケージを使用して、正規表現を扱う基本的な方法を以下に示します。
1. 正規表現のコンパイル
正規表現を使用する前に、まず正規表現パターンをコンパイルする必要があります。***regexp.Compile関数***を使用して正規表現パターンをコンパイルします。
“`go:例
package mainimport (
“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をつけると、エスケープ解析のログを出力することができます
【Go言語】浮動小数点
# 浮動小数点
Goには2つの浮動小数点型がある。
* float32
* float64[Go Playground](https://go.dev/play/p/R-kzEajzx7n)
“`go
var n float32 = 1.0001
fmt.Println(n * n) // 1.0002
“`1.0001 * 1.0001 = 1.00020001ですが、1.0002と出力されます。
小数点は無限に存在するが、float64は有限の64bitである。そのため、丸め誤差が生じ、精度が落ちる時がある。
単精度浮動小数点(float32) : 指数が8ビット、23ビットが仮数を表す。
倍精度浮動小数点型(float64) : 指数が11ビット、仮数が52ビット、残りは符号となる。符号 $S$ 、仮数 $F$ 、指数 $E$ とすると、10進数 $a$ は以下のようになる。
$ a = (-1)^ S \times F \times 2E $
1.0001を上記の式で表すと、
“`math
1.0001 = 1 \times 2^0 \time
Go Development Dashboardとは?
# Go Development Dashboard
https://dev.golang.org/
Goの開発者が見るダッシュボード。
進捗の確認やCLの情報を見ることができる。CLとはChange Listの略で、Pull Requestのようなもの。* [Release](#release)
* [CodeReview](#codereview)
* [Owners](#owners)
* [Stats](#stats)## Release
https://dev.golang.org/release
リリース情報を見ることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156096/5501ed48-fbe3-f5c4-d97c-48df7e3637fa.png)
## CodeReview
https://dev.golang.org/reviews
サブリポジトリに関するCLの一覧。
![image.png](https://qiita-
Dify-Sandbox: 安全な分離環境でコードを実行する
## はじめに
Dify-Sandboxは、信頼できないコードを安全な環境で実行するためのシンプルなソリューションを提供します。複数のユーザーが実行するコードをサブミットできる、マルチテナント環境での使用を想定して設計されています。コードはサンドボックス化された環境で実行され、コードがアクセスできるリソースとシステムコールが制限されます。
—
こちらの記事もおすすめ
https://hamaruki.com/dify-v0-6-9-release-notes/
https://hamaruki.com/difys-docker-compose-upgrade-instructions/
## Dify-Sandboxとは
Dify-Sandboxは、Go言語で書かれたオープンソースのサンドボックスライブラリであり、信頼できないコードを安全に実行するための環境を提供します。
**主な機能:**
* **システムコールの制限:** Linuxのseccomp機能を使用して、実行中のプロセスが許可されたシステムコールのみに制限されます。これにより、悪意のあるコードがシス
【Go】for rangeでmapの要素を取り出す順番
mapの要素をfor rangeで取得する時、取得する要素の順番は必ずしもmapに定義した要素順になる訳ではないらしい。
“`go:
m := map[string]int{
“a”: 1,
“b”: 2,
“c”: 3,
“d”: 4,
}for i := 0; i < 5; i++ { fmt.Println("ループ", i) for k, v := range m { fmt.Println(k, v) } } ``` 実行結果は以下のようになる。 ``` ループ 0 d 4 a 1 b 2 c 3 ループ 1 a 1 b 2 c 3 d 4 ループ 2 b 2 c 3 d 4 a 1 ループ 3 a 1 b 2 c 3 d 4 ループ 4 a 1 b 2 c 3 d 4 ``` この使用は以下の2点を考慮された仕様のようだ。 1. mapの順番が固定されていると仮定したコードを書くのを防ぐ 2. マップの裏で作られるハッシュがいつも同じ対応になると、それを利用して「HashDoS」と呼ばれる攻撃が仕掛けられる危険性
gRPCのクイックスタートを実施してみる!!
## GoでgRPCで構築する方法
gRPCの公式ページのクイックスタートを紹介するものになります。## 前提条件
以下のツールがインストールされていることを確認してください:
– Go: 最新の3つのメジャーリリースのいずれか。インストール手順はGoのGetting Startedガイドを参照してください。
– Protocol buffer compiler (protoc): バージョン3。インストール手順はProtocol Buffer Compiler Installationを参照してください。– Go plugins for the protocol compiler:
“`shell:コマンド
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
“`
PATHを更新して、protocコンパイラがプラグインを見つけられるようにします
“`shell:コマン
【Go】ファイルに追記したいときは、os.OpenFileメソッドでos.O_APPENDフラグを使おう
## はじめに
ファイルに追記するプログラムを書いているときに、追記ではなく上書きされてしまうことがあり、勉強になったので書いておきます。## 上書きされてしまうコード
os.WriteFileメソッドを使うと、ファイルの中身が上書きされてしまう。
“`go
package mainimport (
“fmt”
“os”
)func main() {
err := os.WriteFile(“test.txt”, []byte(“Hello, World!”), 0644)
if err != nil {
fmt.Println(err)
return
}
}
“`## 追記できるコード
os.OpenFileメソッドで、os.O_APPENDフラグを付けると追記できるようになる。
“`go
package mainimport (
“fmt”
“os”
)func main() {
file, err := os.OpenFile(“test.txt”, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0
【Go】依存性の注入をやってみる
## はじめに
PHPやLaravelで依存性の注入は書いたことがあるのでイメージできますが、Goでは書いたことがないので、書いてみました。## コード
Loggerインターフェイスで持たせたいメソッドを定義しています。
そして、そのインターフェイスを満たす実装をしているのが、ConsoleLoggerとFileLogger構造体です。ConsoleLoggerはコンソールに出力するだけ。
FileLoggerは指定ファイルにログを書き込みます。Service構造体にはLoggerインターフェイスを持たせて、ConsoleLoggerとFileLoggerのどちらでも入れられるようにしています。
実際にはコンストラクタとしてNewServiceメソッドで注入しています。こうすることで、Loggerインターフェイスを実装しているものなら好きなようにコンストラクタで差し替えることができます。
インターフェイスを満たすモックを作ることで簡単にテストすることも可能になります。“`go
package mainimport (
“fmt”
“os”
)type
Go言語のデータ型チートシート
# Go言語のデータ型チートシート
こんにちは、皆さん!今回は、Go言語で使用できるさまざまなデータ型をまとめました。
## Go言語のデータ型
| データ型 | サイズ | 説明 |
|—————-|————–|———————————————————————-|
| `bool` | 1ビット | 真偽値(`true`または`false`) |
| `int` | 32ビットまたは64ビット | 符号あり整数。サイズは実行環境に依存 |
| `int8` | 8ビット | 符号あり整数。範囲は
【Go】 スライスをコピーした時のメモリの共有
# スライスのメモリ共有
スライスからサブスライスを切り出す際はコピーを作成している訳ではなく、スライスとメモリを共有してサブスライスが作成される。
つまり、スライス・サブスライス共に要素を変更するとメモリを共有している箇所が影響を受ける。“`go:
x := []int{1, 2, 3, 4}
y := x[:2]
z := x[1:]
x[1] = 20
y[0] = 10
z[1] = 30
fmt.Println(“x:”, x) // x: [10 20 30 4]
fmt.Println(“y:”, y) // y: [10 20]
fmt.Println(“z:”, z) // z: [20 30 4]
“`ここでappendした場合の動きを確認してみる。
“`go:
x := []int{1, 2, 3, 4}
y := x[:2]
z := x[1:]
y = append(y, 10)
z = append(z, 20)
fmt.Println(“x:”, x) // x: [1 2 10 4]
gRPC入門
ノリでgRPCを勉強してみようと思ったら楽しかったので書きます。
## gRPC is 何
公式ページは[こちら](https://grpc.io/)。
ざっくりサマるとハイパフォーマンスなRPC(Remote Procedure Call)のこと。
異なるサービス間のやり取りを実装するプログラミング言語に縛られずにストリーミングでの情報伝達も可能にするRPCの一種です。
データフォーマットにProtocol Bufferを使いバイナリ化され、型付けされたデータを転送できる。
使いどころとしては例えば
– Microserviceのバックエンドサーバー間の通信
– モバイル向けがサービスの通信(通信量を節約)
– スピードを求められる通信などがある。
またgRPCではHTTP/2を使うため、HTTP/1.1では実現できなかったサーバープッシュなどが可能である。
| HTTP/1.1 | HTTP/2 |
| — | — |
| 1リクエスト1レスポンス | ストリームで1TCP接続で複数のリクエストとレスポンスが可能 |
| ヘッダーなどのオーバーヘッド |
Go言語でYahoo!ショッピングの商品検索を行う。
# やりたいこと
Go言語の勉強の一環として、Yahoo!ショッピングの商品検索結果を取得するプログラミングを作成する。
# 環境
* Windows 11 Pro
* Go バージョン 1.22.4# 事前準備
Yahoo!デベロッパーネットワークにアプリケーションを登録し、Client IDを取得する。
https://developer.yahoo.co.jp
![スクリーンショット 2024-07-12 144237.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/66f1666d-294b-bcda-8e6b-fd1a61f09870.png)
# コード
“`main.go
package mainimport (
“context”
“encoding/json”
“fmt”
“io”
“net/http”
“time”
)type Response struct {
TotalResultsAvailable int `js