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

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

[技育CAMPキャラバン]GitHubの統計情報を用いたユーザーのランク付け

# 概要
2024年2月3日に東京で行われた技育CAMPキャラバンハッカソンに参加しました。

本ハッカソンにてGitHub統計情報からユーザーをランク付けして画像を生成するGitHub Personaを作成したのでその概要や感想を書こうと思います。

サービスURL: https://read-me-psi.vercel.app/
GitHubレポジトリ: https://github.com/tomoish/github-persona

# サービス概要
GitHub Personaは、GitHubの統計情報を取得し、ユーザーに異世界系の世界観で役職とランクを割り当てるサービスです。

以下はその一例です。

![result_tomoish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507134/44d6bc32-d0b8-7f5e-6951-90ee413540d8.png)

# システム
今回は以下のような設計としました。

![github-persona-system-desi

元記事を表示

【JavaScript】let宣言は for ループに特化される

# はじめに
次の記事を読んで、JavaScriptのfor文における`let`宣言のループ変数が各ループごとに異なる変数としてバインディングされる動作に違和感を覚えました。

https://qiita.com/twrcd1227/items/e7541a196d6bc1422dac

以下では、違和感を覚えた理由と、調査を進めた結果たどり着いた結論について書いています。

# 結論
結論から言うと、JavaScriptの言語仕様において、`let`はforループに特化されるので、ループ本体のスコープ内でループ変数の作成・値のコピーがされることがわかりました。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for#初期化ブロックの字句の宣言

> 初期化ブロックの字句の宣言
>
> 初期化ブロックのスコープ効果は、宣言がループ本体の中で行われ、condition部分とafterthought部分でアクセス可能であるかのように理解できます。より正確には、`let`宣言はforループに

元記事を表示

cobraとhuhを使って毎日のニュースをチェックできるCLIアプリを作ってみるハンズオン

# はじめに
こんにちは!最近はGoを集中的に触っているのですが、Goを使うと簡単にCLIアプリを作れることを知りました。本記事では、**cobra**と**huh**を使い、毎日の最新ニュースを取得し、LINEに通知してストックするCLIアプリをハンズオン形式で作ってみたいと思います。

:::note
技術記事だけでなく、ちゃんとニュース記事も読むべし!というモチベーションです。
:::

# 実装するもの
![news-cli.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816396/28e84a20-a4cd-fc1c-ffda-4600d0bf2a1f.gif)

コードはこちらです。

https://github.com/ayanami274/mynews-cli

# 使用技術
– go 1.21
– cobra v1.8.0
– huh v0.3.0
– News API v2
– LINE Notify API

### cobraとは
cobraはCLIアプリケーションを作るた

元記事を表示

goのfor文を用いて構造体に変数代入しようとしたら頭を抱えた話

# 問題
`User`構造体の`introduction`を`Introduction`構造体に代入しようとしたら、全て一番最後のプロパティの値が代入されてしまった
## ソースコード

“`golang
package main

import “fmt”

type User struct {
name string
age int
introduction string
}

type Introduction struct {
introduction *string
}

func main() {
users := []User{
{“Alice”, 25, “Hello, I’m Alice!”},
{“Bob”, 30, “Hi there, I’m Bob.”},
{“Charlie”, 22, “Greetings! I’m Charlie.”},
}
introductions := makeIntroductions(users)

for _, introduction := range intr

元記事を表示

Go言語で実装するダイクストラのアルゴリズム: 重み付きグラフでの最短経路探索


Go言語で実装するダイクストラのアルゴリズム: 重み付きグラフでの最短経路探索

人は、生まれながらにして、ゴールが決まっている。

いつ、どこで、どのように死ぬのかが決まっているのだ。

問題はそれを最短経路で行くのか
遠回りしていくのか、だ。

死ぬ時期が決まっているのなら
そこに深みを持たせるしか価値は見出せない。

また、その経路も一つではない。

また、誰もどこがゴールかもわからない。

また、何に価値があるのかも決まっていない。

人生という名の迷路は
いかなるアルゴリズム、プログラムをもってしてでも解けないだろう。

ただ一つ、我々が幸運なことは
この迷路には行き止まりがないという事だ。

**目次**
– [1. ダイクストラのアルゴリズムとは](#1-ダイクストラのアルゴリズムとは)
– [2. コード例](#2-コード例)
– [3. おわりに](#3-おわりに)

## 1. ダイクストラのアルゴリズムとは

 ダイクストラ法(Dijkstra’s algorithm)とは、様々な

元記事を表示

[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-おわり

元記事を表示

OTHERカテゴリの最新記事