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

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

DiscordBotをPythonからGoにリプレイスした話

# はじめに
こんにちは。社会人1年目のサーバーサイドエンジニアのマグロです。
コロナの熱にうなされながら書いてます。

今回は「1周年!若手エンジニアふんわりLT Day!」で発表した「DiscordBotをPythonからGoにリプレイスした話」をしていこうかと思います。

https://wakate-funwari-study.connpass.com/event/323430/

# bot概要
以下はリプレイス前のBotのコードです。

https://github.com/maguro-alternative/discordfast

機能は
– LINEとのメッセージ連携
– ボイスチャンネルの入退室通知
– Web版VOICEVOXによる読み上げ機能
– niconico,YouTubeのWebhook通知
– 上記を管理するadminページ

になります。

botは“`pycord“`、webは“`FastAPI“`&“`jinja2“`&“`bootstrap“`を採用しています。

# 負債一覧
– Pythonで導入しているパッケージが多い。

元記事を表示

GCPのBillingをDatadogに送るアプリをGoで作った

# 対象者(読むと嬉しくなるかもしれない人)
– GCPのBilling周りの通知をメール以外のプロダクトに飛ばしたい人
– Datadogを使用している人

# 前書き
GCPのBillingは現状メールアドレス宛てにしか飛ばせず、`予算とアラート`の機能でPub/Sub トピックにデータを送ったりもできるんですが、これが予算を超えると1時間毎にPub/Subにデータが送られてくるんですよね。アプリ側で1度送信されたらそのフラグを管理するようにすればよいのですが、フラグを管理するためだけにデータソースを用意するのも大仰だな。と思ったことと折角BigQueryに出力しているのであればそれを使えばよいか。と思ったので作ってみました。
また、現状AWSのコストもDatadogに送っていることやDatadog側でMonitoringの種別を色々便利に使える(例えばForcastMonitoringで使用料金の上がり幅が急激だったり)といったことも理由にあります。

ちなみにメールからZapier等を使ってメールからslackに飛ばしてもいいんですが、自分の会社の環境だと連携が定期的に削除され

元記事を表示

Go言語でsortした時の並び順を初歩的に調査してみた

## 疑問

データをsortした時に文字列はどのような基準で順番が決められるのか。

## 結論

標準ではUnicodeコードポイントを判定して、sortをした時に順番が決まる。

## 実装

“`go
package main

import (
“fmt”
“log”
“sort”
)

type Person struct {
FirstName string
LastName string
Age int
}

func main() {
people := []Person{
{“Bob”, “lob”, 27},
{“Tom”, “aoi”, 13},
{“Roberto”, “kei”, 54},
}

fmt.Println(“sort前”, people)

// peopleのデータがなかったらエラーを出す
if len(people) == 0 {
log.Fatal(“データがありません。”)
}

// ソートする
sort.Slice(people, func(i int, j int) bo

元記事を表示

Goでテーブル駆動のベンチマークをとる方法

公式に記載ありますが、まとめてみます。

[公式サイトのブログ記事](https://go.dev/blog/subtests#table-driven-benchmarks)

# ベンチマークのシナリオ

– 数値を文字列に変換する関数を作った。
– 標準パッケージが提供する同種の関数と、パフォーマンスの比較をしたい。
– テーブルとして用意したテストケースそれぞれについて比較をしたい。

# 書き方(ベンチマークの部分のみ)

“`go
type testcase struct {
name string
input []int
}

var testcases = []testcase{
{ // このテストケース単位で、標準パッケージ関数との比較をしたい。
name: “plus”,
input: []int{1, 2, 3},
},
{ // このテストケース単位で、標準パッケージ関数との比較をしたい。
name: “minus”,
input: []int{-1, -2, -3},
},
}

func BenchmarkStringe

元記事を表示

Go言語(golang)でGoogle Cloud Storageを操作する際の共通部分をメソッド化する

### 概要
Go言語でGCS(Google Cloud Storage )のデータを操作する際に、ファイルのアップロード、取得、削除といった処理で共通部分があります。
共通部分をメソッド化して使いまわしたかったのですが、公式のドキュメントだとdeferを使っており、どのようにメソッドにしたらよいかわからなかったので、自分なりに調べて考えた結果を残しておきます。

### やりたいこと
GCPに対する操作について公式のドキュメントをみてみると、以下の部分は共通化できそうです…

https://cloud.google.com/storage/docs/uploading-objects?hl=ja

https://cloud.google.com/storage/docs/deleting-objects?hl=ja
“` go
// bucket := “bucket-name”
// object := “object-name”
ctx := context.Background()
client, err := storage.NewClient(ctx)

元記事を表示

GoのGORMを使ってみる

# はじめに
`Gorm`って使ったことありますか?
Goでは、コードないにsqlクエリを書いて`github.com/go-sql-driver/mysql`を使えば、データベース操作が行えると思います。

しかし、Djangoなどのmodelを定義するだけでデータベース操作が行えてしまうフレームワークのみを過去に触っていた人は、`sqlクエリ`の書き方がわからず苦戦すると思います。
それにいくらsqlが書けたとしても、長々と`sql`を書きたくないですよね。

なので、今回はそれを解決する`GORM`を使ってみようと思います。

# GORMとは
`GORM`とは、Go言語のORMライブラリです。

ORMって言われてもわからないですよね。

まずはORMから説明します。

### `ORM`とは

オブジェクト関係マッピング(Object-Relational Mapping)の略称で、オブジェクト指向におけるクラスや構造体とデータベースを紐付ける技術のことを指します。Djangoでモデルを定義するだけで、データベース操作が行えたのは標準でORMが使われていたからです。

`メリ

元記事を表示

ES自動生成AIを作ってみた

この記事では以下の拡張機能(ES-writer)を作成した時のことについて記していく。

https://github.com/Yutosaki/es-writer/tree/main

目次
* なぜ作ったか
* どの様に作り始めたか (技術構成など)
* 機能
* 推しポイント
* 上手くいったところ
* どこが苦労したか
* 今後の展望

また、別記事でコードについての解説などもしようと考えている。

# なぜ作ったか
現在自分が大学3年で様々な企業にエントリーシート (ES) を出していたが、毎回おんなじ様な内容をちょっとフォーマットが違ったり、文字数の制限があったりでわざわざ書き換えるのが面倒に感じたため、これらをもっと簡単にできないかと考えた。

# どの様に作り始めたか
そもそもなのだが、これはハッカソンで作ったものである。
(Progateハッカソン powered by AWS エムスリー株式会社賞 受賞 🎉)
最初は、普通にWebアプリケーションで作ろうと考えていた。期間も約1週間ほどで、5人で挑んだのだが5人中2人がハッカソンなどの開発が初めて、という状況もあり、

元記事を表示

動体検知監視カメラ

# はじめに

今回、自作で動体検知のできる監視カメラを作成しました。本記事では、開発にあたって設定した要件をまとめてご紹介します。

# 1.テーマ
「自身で開発から運用までを行い監視カメラを作る」という目標のもと開発した、動体検知で人間のみを検知し、discord(メッセージアプリ)に検知時の画像を送信するアプリケーションです。

# 2.課題の定義
## 解決すべき課題
実家に空き巣が入り、急遽、市販の監視カメラを設置しました。しかし、運用するにあたって、いくつかの課題を発見するに至りました。
#### 2.1 可用性の問題
– 上手く動体検知しないことがある
– デバイスに送信される画像がコマ送りになっており、前後の映像が取得できない
– 画質が悪く、正確な情報を得られない
#### 2.2 ユーザビリティの問題
– 専用アプリが使いにくく、独自の設定をユーザ側が手動で行う必要がある
– アプリの通知が届かない時があり、検知した場合に即座の対応が難しい

## 3.解決方法
フルHDのwebカメラを使用し、Discordを介して画像を送受信することで、画質の問題・通知の不安定

元記事を表示

Go のリスト分割

リストを指定のサイズで分割して返す関数を用意した。
誰かが使うかも知れないので、共有しておく。誰も使わなかったら自分で使おう。

“`go
func Split[T any](elms []T, size int) [][]T {
if size <= 0 { return [][]T{elms} } var split [][]T for 0 < len(elms) { s := size if len(elms) < size { s = len(elms) } split = append(split, elms[0:s]) elms = elms[s:] } return split } ``` テストケースも併せて用意。 ```go func TestSplit(t *testing.T) { tests := []struct { name string elms []string size int want [][]string }{ { name: "partial", elms: []s

元記事を表示

Cloud Functions(2nd Gen)を使い始める上で知っておきたいことメモ(Go)

Cloud Functions で非同期ワーカーをサクッと作ろうと着手し始めたら、第二世代になって色々と変わっていて「あ、ここに書いてあったの?」というものが多かった…。

そこで当記事では、「チュートリアル以上のことをしようとした時に、ドキュメントを読み始める前に知っておくとつまづきが減るかもしれない前提知識」 を整理していきたいと思います。

:::note info
* 当記事では Go 言語を前提として説明していきます
* 2024年8月時点の情報ですので、最新情報はドキュメントをご確認ください
:::

## Cloud Functions 2nd Gen. のアーキテクチャ
ドキュメントを読んでいくと、Go 言語での実装は以下のように案内されている。

**・HTTP関数のサンプル**
“`go
package myhttpfunction

import (
    “fmt”
    “net/http”

    “github.com/GoogleCloudPlatform/functions-framework-go/functions”
)

func ini

元記事を表示

Goの簡易文付きif文について

# Goの簡易文付きif文についての個人的な考察

Goでは、簡易文付きif文を使用することで、エラーハンドリングをより簡潔に書くことができる
しかし、個人的には早期リターンを用いた従来の書き方の方が可読性が高まると考える

## 書き方
ReadAlbumTitle関数からの戻り値(album構造体とerror)を処理する例

“`golang:簡易文付きif文
if album, err := ReadAlbumTitle(file); err != nil {
return err
} else {
albumList = append(albumList, album)
}
“`

“`golang:従来の書き方(早期リターン)
album, err := ReadAlbumTitle(file)
if err != nil {
return err
}
albumList = append(albumList, album)
“`
## 可読性
・簡易文付きif文で

元記事を表示

Goでスクレイピングをやってみる

みなさんスクレイピングを知っていますか?

スクレイピングとは、webサイトのHTML要素をプログラムを使って取得することです。

今回は、以下のスクレイピング練習サイトでGoの`colly`というライブラリを使って、スクレイピングを行ってみました。

https://books.toscrape.com/

# スクレイピングを行う際の注意事項
スクレイピングは、注意して行わないと違法になる可能性があります。
今回、自分が調べられる範囲で注意しなければならないことを調べてみました。

### まず利用規約を確認する
利用規約には、スクレイピングを禁止しているサイトがいくつかあるそうです。
例えば、`Amazon`の利用規約には以下のような文言があります。
>この利用許可には、アマゾンサービスまたはそのコンテンツの転売および商業目的での利用、製品リスト、解説、価格などの収集と利用、アマゾンサービスまたはそのコンテンツの二次的利用、第三者のために行うアカウント情報のダウンロードとコピーやその他の利用、データマイニング、ロボットなどのデータ収集・抽出ツールの使用は、一切含まれません。

元記事を表示

バックスラッシュエスケープされたタブ区切りテキストをCSVに変換する

以下サンプル

“`tsv2csv.go
//usr/bin/go run $0 $@ ; exit
package main

import (
“bufio”
“encoding/csv”
“fmt”
“os”
“strings”
)

func main() {
// 標準入力からデータを読み込む
scanner := bufio.NewScanner(os.Stdin)

// CSVライターを作成し、標準出力に書き込む
writer := csv.NewWriter(os.Stdout)
defer writer.Flush()

// 標準入力を1行ずつ読み込み
for scanner.Scan() {
// タブ区切りでフィールドを分割
line := scanner.Text()
fi

元記事を表示

初心者向けGo言語入門講座。今日から開発したい方向け

# Go言語入門講座

## Chapter 1: Go言語の紹介
Goは、Googleによって開発されたオープンソースのプログラミング言語で、シンプルで効率的なコードを書くことができます。Goの特徴や利点について説明します。

## Chapter 2: 開発環境のセットアップ
Goのインストール方法と開発環境のセットアップについて説明します。Goの公式サイトからダウンロードし、インストールします。

“`bash
# macOSの場合
brew install go

# Windowsの場合
# Goの公式サイトからインストーラーをダウンロードして実行
“`

## Chapter 3: Goプログラムの基本構造
Goプログラムの基本構造を学びます。`main`関数と`package`宣言について説明します。

“`go
package main

import “fmt”

func main() {
fmt.Println(“Hello, World!”)
}
“`

## Chapter 4: 変数と定数
Goでの変数と定数の宣言方法を学びます。型推論と型指

元記事を表示

Docker 環境と Go Gin で最小 API を実装する:MongoDB

# Docker 環境と Go Gin で最小 API を実装する:MongoDB

こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 24.04 で Go Gin Web アプリケーションを作成し、最小限の REST API を実装する方法を紹介します。
![gin_and_mongodb_on_docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/7c454da9-77e3-ef2a-7052-6019a0146e32.png)

## 目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

https://qiita.com/studio_meowtoon/items/6119ab05d8b13527efd8

## 実現すること

ローカル環境の Ubuntu の Docker 環境で、Dockerfile からビルドした Go Gin サービスのカスタムコンテナーと Mongo

元記事を表示

go-mysql-serverを使ってテンポラリなDBを立ち上げてテストを行う

最近、新しいプロジェクトで、久しぶりにGoを書いています。

DBを使ったコードのテストをしたいという要求が自分の中にあってどうしようかなと考えたところ、[go-mysql-server](https://github.com/dolthub/go-mysql-server)を使ってみることにしました。
dockertestやtestcontainersとかもあるよう(参考: [紹介記事](https://zenn.dev/jy8752/articles/419ab77b2b6a61))ですが、こっちのが速いかなというただの印象で、使うことにしました。後々dockertestやtestcontainersも使えるようにしても良いかなとは思ってはいます。

なお、本当のMySQLではないので、[制限](https://github.com/dolthub/go-mysql-server?tab=readme-ov-file#limitations-of-the-in-memory-database-implementation)はあります。
制限の簡単な訳と使ってみての追加(最後の2つ)

元記事を表示

自分がよく個人開発で使うターミナルコマンドまとめ(フレームワークなど)

## はじめに
初めましての人もそうでない人もこんにちは!
今回は自分がよく使うターミナルコマンドをまとめたいと思います!

皆さんは個人開発をよくしますか?
自分はコミュ障なのでなかなかチーム開発の機会なんてほとんどありません

まぁ自分がコミュ障なのは置いておいて個人開発する時って大抵Reactを使うためにnpx・・・と長いコマンドを使ったりしてませんか?

そんな長いコマンドを毎回のように入力することが大変面倒でChatGPTとかに毎回教えてもらっています!

コマンド用のテキストファイルを作成しましたが毎回のようにローカルファイルの海に漂っています・・・

なので今回は主に自分用という部分が大きいですが、皆さんにも共有できたらと思いこの記事を作成しました!

## React + TypeScript
“`
npx create-react-app frontend –template typescript
cd frontend
npm start
“`

## venv + Python
### MacOS/Linuxの場合
“`
python -m venv ve

元記事を表示

Goのモックライブラリを比較検討する

# 概要
Goのモックライブラリはいくつか存在しており、検討を始めるにあたって [Comparison of golang mocking libraries](https://gist.github.com/maratori/8772fe158ff705ca543a0620863977c2#user-content-fn-12-14e5dadb9d5bbfc4c34632f365c8a95b)の内容が大変参考になった。

このうち候補として考えた gomock, mockery, moq をそれぞれ使ってテストコードを書いてみた所感を元に、比較検討した結果をまとめる。

# はじめに:なぜモックライブラリが必要なのか
Goのテストコードで依存するインターフェースをモックする時、モックライブラリを使わずとも自前でモックを実装することは可能である。
例えば、以下のような `GetUserService.Get()` のテストコードを考えてみる。

“`go
type UserRepository interface {
GetUser(userId string) (User, er

元記事を表示

初めてGo言語をやってみて分かったこと。

# C言語と最近のモダンな言語(Java、C#、Pythonなど)のいいとこ取りをした感じ

* C言語的要素

基本的にGo言語はコンパイラ言語であり、ビルドを実行すると機械語に変換されるのですが、
機械語は直接CPUに命令を出す形式なので、めちゃくちゃ動作スピードが早いです。
コンパイラ言語はGo言語以外に、C言語、C++、Rust等があります。

また、Go言語はクラスという概念は存在しないので(似たようなパッケージという概念はありますが)、
その点も同じと言えます。

* Java的要素

モダンな言語だと、C言語には無かったListのような、要素を自由に追加削除できるるような仕組みがあります。
最近の言語だから、こういった仕組みなども扱えるようになっています。

また、例外処理(try-catch)のような仕組み(panic-recover)も用意されています。

* Python的要素

Pythonのようなスクリプト言語はソースファイルをあれこれ変換しなくてもすぐに実行できるのが特徴ですが、Go言語もいちいちビルドする必要は無く、ソースコードの状態のままで実行できるオプシ

元記事を表示

Goのネットワークプログラミングでよくあるエラーのbroken pipeを深く理解するために

Goでネットワークアプリケーションを開発する際、時々「broken pipe」というエラーに遭遇することがあるでしょう。この記事では、このエラーの意味を説明して、再現するためのコードを示して、基本的な対処法をいくつか紹介します。

「broken pipe」は通常、**(通信している同士の一方が)相手がリセットした(RST)TCPコネクション**にデータを書き込もうとしたときに発生する。このエラーは以下のコードで再現できる。

“`go
// …
var done = make(chan struct{})

func server() {
listener, err := net.Listen(“tcp”, “:8080”)
if err != nil {
log.Fatal(err)
}
defer listener.Close()

done <- struct{}{} conn, err := listener.Accept() if err != nil { log.Fatal("S

元記事を表示

OTHERカテゴリの最新記事