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

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

[Go言語]ワーカープールパターン並列処理 メモ

* Go言語におけるワーカープールパターン並列処理についてメモする。

## ワーカープールパターンとは

* 複数のタスクやジョブを効率的に処理するためのデザインパターン。
* 特定の数のワーカー(ゴルーチンなど)を用意し、これらのワーカーがタスクキューからタスクを取り出して並行処理することで、リソースの使用効率を最適化し、処理速度を向上させる。

### 概念

“`mermaid
graph TD
A[タスクキュー] –>|タスクを提供| B(ワーカープール)
B –>|タスク1を処理| D[ワーカー1]
B –>|タスク2を処理| E[ワーカー2]
B –>|タスク3を処理| F[ワーカー3]
B –>|タスクNを処理| G[ワーカーN]
D –> H[結果]
E –> H
F –> H
G –> H

“`

– **ワーカー**:
– 同時に実行されるタスクやジョブを処理する単位(スレッドやゴルーチンなど)。
– ワーカープール内の各ワーカーは、タスクキュ

元記事を表示

Go言語における nil の利用時の注意点

Go言語では、nil は特定の型が値を持たないことを示すために使用されますが、その利用にはいくつかの重要な注意点があります。nil の利用時に考慮すべきポイントに焦点を当てます。

### 1. ポインタとnil
Go言語において、ポインタ型の変数はデフォルトでnilとなります。未初期化のポインタは、特定のメモリアドレスを指しておらず、注意して扱う必要があります。

“`go
package main

import “fmt”

func main() {
// int型の変数を宣言
var myInteger int

// int型のポインタを宣言し、未初期化(nil)で初期化
var myPointer *int

// ポインタがnilであることを確認
if myPointer == nil {
fmt.Println(“ポインタはnilです。”)
}

// ポインタに変数のアドレスを割り当て
myPointer = &myInteger

// ポインタがnilでないことを確認
if myPointer != nil {
fmt.Pr

元記事を表示

GO言語における nil と null の違い

GO言語において、nil と null は似ているようで異なる概念です。これらの用語は、異なるプログラミング言語で使われることがあり、それぞれの言語において異なる挙動を示すことがあります。GO言語では、nil という用語がより一般的に使用されていますが、一部の文脈では null という言葉も見られることがあります。

### 1. nil の使用
GO言語では、nil は主に[ポインタ、スライス、チャネル、マップ、インターフェース](https://qiita.com/zhao-xy/items/4fcbf5b64eb4cbf23b6c)、関数などの特定の型の変数が値を持たないことを示すために使用されます。例えば、ポインタの初期値は通常 nil です。

“`go
package main

import “fmt”

func main() {
var myPointer *int
if myPointer == nil {
fmt.Println(“ポインタはnilです。”)
}

}
“`

“`
ポインタはnilです。
“`

### 2. null の使用

元記事を表示

【Git】モノレポ時のDev Containerにおけるバージョン管理

# はじめに
 サービス開発、特にAPIをコンパイル言語で構築する場合、[Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)を用いると便利である。しかし、モノレポ構造でサービスを開発している場合、.gitリポジトリが親ディレクトリに存在することでVSCodeがリポジトリを認識しない。gitコマンドを利用する際にVSCodeをLocalでReOpenし対応可能だが、現実的でない。
 今回はモノレポ構造の開発環境でDev Containerを用いた際にGitでバージョン管理を行う方法についてまとめる。

# ディレクトリ構造
 開発を行うにあたり、ディレクトリ構造の抜粋を以下に示す。
> root/
> ├ .git
> ├ .devcontainer/
> │ └ devcontainer.json
> ├ backend/
> │ └ build
> │   └ package
> │     └ Dockerfile
> └ d

元記事を表示

楽天トラベルAPIを使ってみた


楽天トラベルAPIを使ってみた

**食べ頃のプリン**

友達の髪が茶髪から色が黒みを取り戻し、プリンみたいな感じになってました。

「食べ頃だね」

と私がいうと

「あ、いい感じの焦がしプリンでしょ」

と言いました。

甘い プリンって いいよね
API……。

**目次**
[1. 楽天トラベルAPIとは](#1-楽天トラベルapiとは)
[2. Go言語で簡単な実装してみた](#2-go言語で簡単な実装してみた)
[3. おわりに](#3-おわりに)

# 1. 楽天トラベルAPIとは

 APIでなんか遊んでみたいと思い、楽天トラベルAPIというものを使ってみました。

 楽天トラベルAPIは、楽天トラベルが提供するウェブサービスの一つで、開発者が楽天の旅行関連のデータや機能を自分のアプリケーションやウェブサイトに統合することができるプログラミングインターフェースです。

 まず、Rakuten Developersへアクセスし、アカウントを登録します。
[Rakuten Developers](https://w

元記事を表示

GoでgRPCサーバーを立ててみる4(service.go、server.goの実装)

お疲れ様です。

今日は「service.go、server.goの実装」について部分いたします。

# service.goの実装

repositoryでやり取りしたデータをもとにgRPCのレスポンスを返すservice.goの実装をしていきます。

“`article/service/service.go
package service

import (
“context”

“github.com/k88t76/GraphQL-gRPC-demo/article/pb”
“github.com/k88t76/GraphQL-gRPC-demo/article/repository”
)

type Service interface {
CreateArticle(ctx context.Context, req *pb.CreateArticleRequest) (*pb.CreateArticleResponse, error)
ReadArticle(ctx context.Context, req *pb.ReadArticleRequest) (*pb.

元記事を表示

go test時に”%1 is not a valid Win32 application”とエラーが出る

# 概要

題名通り、ある日 `go test` を実行したら
“`
fork/exec C:\Users\XXX\AppData\Local\Temp\go-build2550557918\b001\YYY.test:
%1 is not a valid Win32 application.
“`
とエラーが出て失敗するようになったので、その原因と解消方法を調べた結果をメモした記事です。

蓋を開けると非常にしょうもない&滅多にない原因なので記事としての価値は微妙ですが、同じような事態に遭遇した方のために書き残しておきます。

# 原因: GOOS、GOARCHの設定がおかしかった
結論から言うと、上記エラーが出る前、Goのクロスコンパイルについて調べたり遊んだりしていて[^1]、
“`zsh
go env -w GOOS=linux GOARCH=arm64
“`
を実行したまま後始末していなかったのが原因でした[^1-2]。

Goはビルド時の想定OSや`go install`のインストール先など諸々の環境依存の設定を環境変数で管理しており、`go env -w` はそ

元記事を表示

Go言語のスライスでよくある勘違いとその解説

Go言語のスライスは非常に強力な機能を提供しますが、理解しにくい部分もあります。ここでは、Go言語のスライスを使用する際によくある勘違いや混乱の原因となるポイントをいくつか紹介し、それらを明確にします。

### 1. スライスと配列の違い

Go言語の新規ユーザーはしばしばスライスと配列を混同します。配列は固定長であり、そのサイズはコンパイル時に決定されますが、スライスは動的な長さを持ち、実行時にサイズが変更可能です。配列をスライスに変換することはできますが、その逆は直接的には行えません。

### 2. スライスの長さと容量

スライスの[「長さ」と「容量」](https://qiita.com/zhao-xy/items/a2bba7619ba10b02f38a)は異なる概念ですが、これらが混同されることがあります。長さはスライスに含まれる要素の数を指し、容量はスライスの背後にある配列が持つ要素の最大数を指します。`append`を使用してスライスに要素を追加すると、必要に応じて容量が自動的に増加しますが、この挙動を誤解すると予期せぬパフォーマンスの問題が発生する可能性があります

元記事を表示

Go言語におけるスライスの長さと容量のちがい

GO言語のスライス(Slice)は、動的なサイズを持つ配列のような構造です。スライスは、配列よりも柔軟にデータを管理することができ、Go言語におけるデータの扱いをより効率的にします。スライスの「長さ(length)」と「容量(capacity)」は、この柔軟性の核となる概念です。

#### スライスの長さ(Length)
スライスの「長さ」とは、スライスが現在含んでいる要素の数です。len()関数を使用してこの値を取得できます。例えば、

“`go
package main

import “fmt”

func main() {
s := []int{1, 2} // 長さが2のスライスを作成
fmt.Println(len(s))// 長さ
}
“`

“`
2
“`

#### スライスの容量(Capacity)

スライスの「容量」とは、スライスが背後で確保している配列のサイズです。これは、スライスに追加可能な要素の最大数を意味し、cap()関数によって取得できます。容量は、スライスに新たな要素を追加する際に、背後の配列が再割り当てされるかどうかを決定する重要な要

元記事を表示

Go言語色んなサイズを測ってみました


Go言語色んなサイズを測ってみた

**目次**
[1. 色んなタイプのサイズ比較](#1-色んなタイプのサイズ比較)
[2. まとめたテーブル](#2-まとめたテーブル)
[3. おわりに](#3-おわりに)

# 1. 色んなタイプのサイズ比較

 Go言語の仕様を学ぶため、色んなタイプのサイズを比較してみました。

 一覧は最後のテーブルにまとめます。

+ この比較は、以下の環境で行われています:
+ システム:Mac
+ アーキテクチャ:64ビット
+ Goのバージョン:go version go1.18.1 darwin/amd64

“`go
go version go1.18.1 darwin/amd64
“`

 比較するデータ型は以下の通りです:

“`go
1. int / uint (サイズはアーキテクチャによって異なる場合がある)
2. int8 / uint8
3. int16 / uint16
4. int32 / uint32
5. int64 / uint64
6. float32

元記事を表示

【Go/Gin】画像をアップロードしてディレクトリ内に保存する

## やりたいこと
画像をGinのAPIサーバーへアップロードし“`./images“`ディレクトリに保存したい。

## 実装方法
“`go:main.go
package main

import (
“net/http”
“path/filepath”

“github.com/gin-gonic/gin”
)

func main() {
router := gin.Default()
router.MaxMultipartMemory = 8 << 20 router.POST("/images", func(c *gin.Context) { file, err := c.FormFile("images") if err != nil { c.String(http.StatusBadRequest, "get form err: %s", err.Error()) return } savepath := filepath.Join("images", file.Filename) if err := c.SaveU

元記事を表示

Go学習2周目でのつまづいたところの気付き

## Goを1から学んでみた
この度Go言語を独学で学んで実務で使うことになりました。
チュートリアル、本、Udemyの講座で一通りGoの文法を学んでみて、1ヶ月経った後に実務で使うことになったのですが、1周目では気づかなかったけど2周目で腑に落ちて学べたことをメモします。
Go言語をやっている人には当たり前のことですが、他言語からスキルチェンジした人にとっては共感できることもあるかもしれません。

### packageはディレクトリごとに管理する
Goではファイルの先頭にpackageをまず宣言するが、それは同じディレクトリにあるものは同じpackageを使うのが慣例。

### 同じpackageにある定数や関数はそのまま使える
同じlessonというpackageに属している2つのファイル間で定数numberを共有できる。

“`go:lesson.go
package lesson

const number int = 3
“`

“`go:lesson_test.go
package lesson

const number2 int = number
“`

元記事を表示

Go + GoLand + DevContainer + Air + delveのイケイケ環境構築でデバッグを行う。

# 概要
本記事ではGo言語を手っ取り早く動かせる環境を構築したい方向けの記事です。
良ければ、参考にしてください。
## TL;DR
ディレクトリ構成がクリーンアーキテクチャを意識しているので、若干違いますが、動作します。
ファイル作成が面倒な方はこちらをどうぞ。
cloneしたらスターもらえると嬉しいです。
https://github.com/sirayusan/business/tree/develop

## 環境
Windows11 Pro
Docker 4.12.0
WSL2 WSL バージョン: 2.0.9.0
Ubuntu 22.04.3 LTS
GoLand 2023.3.2
# 使用技術と開発支援ツール
Docker
DevContainer
GoLand(IDE)
Air(ホットリロード)
delve(デバッガ)
## 言語
Go 1.20
## DB
MySQL 8.0
## ディレクトリ構成
“`
business
├── .devcontainer
│ ├── infra
│ │ ├── go
│ │ │ └── Dockerfi

元記事を表示

GoにおけるAPI並列処理について

### はじめに
APIデータ取得を高速化する方法として、並列処理が有効です。Goの `sync.WaitGroup` を活用し、異なる2つのAPIからデータを並列で効率的に取得する方法を紹介します。具体的な例として、ユーザーデータと製品データの取得を行う架空のシナリオを設定し、直列処理と並列処理のコードを比較します。

### 改善前コード(直列処理)
“`go
package main

import (
“errors”
“fmt”
)

// UserData はユーザーのデータを表す架空の構造体です。
type UserData struct {
ID string
Name string
}

// ProductData は製品のデータを表す架空の構造体です。
type ProductData struct {
ID string
Title string
}

// FetchUserData は架空のユーザーデータ取得APIを模倣します。
func FetchUserData(userID string) (

元記事を表示

Float型の標準出力の有効数字のデフォルトはなぜ6桁なのか


Float型の標準出力の有効数字のデフォルトはなぜ6桁なのか

**風船ガム**

イチゴ味の風船ガムを食べてました。

くちゃくちゃ味わい、ふくらます。
口に広がる甘酢っぱさ。
フルーティーが鼻をつつく。

何回かそれを繰り返していると ふと
どれくらい大きくなるのだろうと
思いました。

おもいっきり息を吐き 
風船ガムをふくらませました。

ドンドン大きくなるガム。

破けることなく大きくなり
ついに私は空を飛びました。

ああ、でも残念なことに
私はずっと上を向いたまま。

下に広がる素敵な景色は見れません。

「私はどこまで浮かびつづけるのでしょうか」

浮かびながら空に聞くのでした。

**目次**
[1. そもそもFloat型って何?](#1-そもそもfloat型って何)
[2. Float型の標準出力の例](#2-float型の標準出力の例)
[3. なぜデフォルトは6桁なのか](#3-なぜデフォルトは6桁なのか)
[4. おわりに](#4-おわり

元記事を表示

Go導入はやっぱり悪戦苦闘するという話

# はじめに
Hubbleでバックエンドエンジニアをしている @power3812 です。オブジェクト指向大好きマンで、神クラスを作れないかと模索の日々です:innocent:

今回は普段Rubyをメイン言語としている弊社がGo導入に悪戦苦闘した話をしようと思います!

## 経緯
弊社ではメインでRuby、サブシステムにJava、Pythonを使用していました。
しかし、社内からエンジニア的な欲求としてGoを使用してみたいという声が多かったのと、エンジニア採用面から使用できる機会を窺っていました。

そんな中、そこまでfatではない[新アプリケーション](https://hubble-docs.com/news/forms)のAPIに使用してみようということになりました。

## 技術選定
今回の新APIは、ほぼ自分1人で担当することになったので予めエコシステム周りを決定していくことにして、以下の構成で行くことにしました。

– フレームワーク – Echo
調べた感じEchoとGinの2大巨頭っぽい
Ginだとワイルドカードパスを使用した共有のルーティングでコンフリクトが発生する

元記事を表示

go-awslambda

“`text
— FAIL: TestSlogtest (0.03s)
\zapslog\logger.go:130: message
\zapslog\logger.go:130: INFO message {“k”: “v”}
\zapslog\logger.go:130: msg {“a”: “b”, “c”: “d”}
\zapslog\logger.go:130: INFO msg {“k”: “v”}
\zapslog\logger.go:130: msg {“a”: “b”, “k”: “v”}
\zapslog\logger.go:130: msg {“a”: “b”, “G”: {“c”: “d”}, “e”: “f”}
\zapslog\logger.go:130: msg {“a”: “b”, “e”: “f”}
\zapslog\logger.go:130: msg {“a”: “b”, “c”: “d”, “e”: “f”}
\zapslog\logger.go:130

元記事を表示

Goの最初に行うinitでの初歩的なミス備忘録

## 発現法

Goのプロジェクトを立ち上げて、`main.go`を作成します。`package main` を記述して`go mod init`コマンドを打ち込んで初期化を行おうとしました。下記のエラー発現。

## エラー内容

“`tsx
go: cannot determine module path for source directory /Users/hogehoge(outside GOPATH, module path must be specified)

Example usage:
‘go mod init example.com/m’ to initialize a v0 or v1 module
‘go mod init example.com/m/v2’ to initialize a v2 module

Run ‘go help mod init’ for more information.
“`

## 解決策

`go mod init あなたのプロジェクト名(モジュール名?)` と最後にモジュール名を指定する必

元記事を表示

ChatGPTを相手に英会話レッスンができるアプリを作成

# 英会話レッスンを(ほぼ)無料でいつでもやりたい!
英会話レッスンを受けたいとき、お金がかかり時間も拘束される。
そこで、ほとんど無料でいつでもpcブラウザやスマホで英会話レッスンができるアプリが欲しいと思い開発することにした。
ほとんど無料である理由は、ChatGPTを呼び出すためにOpenAIのAPIにクエリを投げる際にごく少額の料金がかかるからである。(だいたい1会話0.1円未満)

# アプリの構成
アプリはpcブラウザ、スマホからアクセスできアクセス元の環境に関係なく、前回までの会話を続けられるようにする。
会話の入力はpcブラウザ、スマホの音声入力APIを使って行い、入力に対するChatGPTの応答は音声読み上げAPIを使って読み上げることにより、会話ができる。
また、会話はルーム単位で管理する。
なお、今回は英会話レッスンをすることが目的であるため英会話のみに対応すれば十分であるが、音声入力APIと音声読み上げAPIは多くの言語に対応しているため、中国語、フランス語、スペイン語などAPIが対応している言語のレッスンも本アプリでは行うことができる。(ルーム単位で設定言語を

元記事を表示

ラズベリーパイにgoofysをインストールする

– [kahing/goofys | GitHub](https://github.com/kahing/goofys)

# GOのインストール

ラズパイのOSが32bitか64bitかダウンロードファイルが異なります。
32bitなら `armv6l` 、 64bitなら `arm64` を選択します

“`bash
# パッケージのダウンロード
# GOLANG_DL_URL=”https://go.dev/dl/go1.21.1.linux-arm64.tar.gz” # 64bit
GOLANG_DL_URL=”https://go.dev/dl/go1.21.1.linux-armv6l.tar.gz” # 32bit
wget -O /tmp/go.tar.gz $GOLANG_DL_URL
rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go.tar.gz

# パスを通す
echo ‘export PATH=$PATH:/usr/local/go/bin’ >> ~/.bashrc
source ~/.

元記事を表示

OTHERカテゴリの最新記事