Go関連のことを調べてみた2022年09月06日

Go関連のことを調べてみた2022年09月06日

【MEMO】Goで文字コードを自動判別してCSVを読み込む/文字コードを指定して書き込む

# Goで文字コードを自動判別してCSVを読み込む/文字コードを指定して書き込む

文字コードとか種類多すぎてわからーん。
とりあえずUTF-8, Shift_JIS, EUC-UPくらい対応したい。

今のところは問題なく動いているけど、例外があったら直す。

CSVの文字コード自動判別/指定書き込み

“` Go

package separate

import (
“bufio”
“bytes”
“encoding/csv”
“io”
“os”
“strings”

“github.com/saintfish/chardet”
“golang.org/x/text/encoding/japanese”
“golang.org/x/text/transform”
)

type EncodeType int

const (
UTF8 EncodeType = iota
UTF8BOM
ShiftJIS
EUCJP
)

func ReadFileDetect(filePath string, split rune) ([][]string, Enc

元記事を表示

[Go]並行処理・ゴルーチン

※親記事
[[Go]プログラミングノート](https://qiita.com/WisteriaWave/private/c1ff1250aa5a155debd5)

# 1. 並行処理
Golangで指示できるのは **「並列処理でなく並行処理」** である。

**並行処理と並列処理の違い**

![名称未設定ファイル-並行処理と並列処理.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/09086e58-4207-968e-f33b-49c0735e328b.png)

Golangでは **ゴルーチン** によって並行処理を実装できる。
ゴルーチンを使って、マシンに並列処理してもらうためには、最低でも以下が満たされてなければならない。

– CPUコア数が2以上であること
– GOMAXPROCSを2以上に設定していること

[この記事](https://zenn.dev/hsaki/books/golang-concurrency/viewer/term#%E3%80

元記事を表示

[Go]プログラミングノート

# 概要
Goを勉強してわかったことを少しずつまとめていく

環境構築は以下

https://qiita.com/WisteriaWave/private/450f99358fffc6a6b9f0

# 基本の形
“`main.go
// パッケージ名の宣言
package “main”

// 別パッケージのインポート
import (
“sample”
// …
)

// プログラムは「mainパッケージ」のmain関数から始まる。
func main() {

}
“`

# パッケージ
あるファイルで別ファイルに書いたコードを読み込んで使いたい場合は、
パッケージ単位でインポートする必要がある。
パッケージとは、ファイルを束ねるもので、以下のファイルは同じ「sample」パッケージに所属するものになる。

“`sample_1.go
package “sample”

func Sample1() int {
return 1
}
“`

“`sample_2.go
package “sample”

func Sample2() int {

元記事を表示

[Go]個人学習のための環境構築

# 概要
Golangの勉強のためにやった環境構築についてまとめておく。
実務で役に立つこともあるだろうということで。

**個人的な開発環境**
– goのバージョン: 1.19
– デフォルトシェル: zsh
– エディタ: VSCode

# 1. Goのインストール・設定
## 1.1. インストール
[Go公式のインストーラダウンロードページ](https://go.dev/dl/)へアクセスし、OSにあったインストーラをダウンロードしてインストール

## 1.2. Goのパスを通す
自分の環境ではインストーラでインストールしただけでは、goコマンドが使えずパスがとおっていなかったため、以下を~/.zshrcに記述して“source ~/.zshrc“で反映した

“`
export PATH=”/usr/local/go/bin:$PATH”
“`

パスが通っていることの確認
“`
# バージョンが表示されればOK
go version
=>
go version go1.19 darwin/amd64
“`

# 2. VSCode拡張機能のインストール

元記事を表示

[Go]パッケージ・モジュールまとめ

# 1. パッケージとモジュール

**イメージ図**
![モジュール・パッケージ.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/2429c4b5-faa1-7625-2e75-16e9bf1cf5a2.png)

## 1.1. パッケージ
「ソースファイル(.go)」の集合体。
同じディレクトリ内のソースファイルが、パッケージの構成要素になる。
同じパッケージのソースファイルは一緒にコンパイルされ、関数・変数も共有される(つまり、1ファイルに書いたのと同じ状態でコンパイルされる)。

## 1.2. モジュール
標準ライブラリでない「パッケージ」の集合体。
“go.mod“ファイルがあるディレクトリ以下のすべてのパッケージがモジュールの構成要素になる。
バージョン管理システム(githubなど)の1リポジトリに1モジュールを登録する。
バージョンが違えば、異なるモジュールとみなされる。

goのバージョン1.11から モジュール機能が使えるようになった。

元記事を表示

GoのAPIサーバーの実行にAirを使っていたというお話

Goの初心者です。

発端は、golangの実行方法って

1. `go run main.go`
2. `go build main.go`でビルドして、`./main`で実行

の2種類のはずなのに、Dockerfileにそんな記述ないよ!どうして?

と思ったのがきっかけ。

初心者用の記事だとほとんど`go run main.go`で済ませてるし、開発プロジェクトに入っても、ローカルの実行は`docker-compose up -d [コンテナ名]`などでできてしまうため、あまり意識しなかったのだが、Dockerfile-localをちゃんと最後まで読んでみると、
`CMD [“air”, “-c”, “.air.toml”]` という記述で締めくくられていたため、そこで実行しているのだろうという仮説から題名に戻ることになる。

**Air**とはgolangのホットリロードツールのことである。

ホットリロードとはソースコードを更新するたびにソースをビルドし直して実行するという手間を省くため、ソースコードを更新し、保存したら自動でビルドと再実行を行うということである。

Ai

元記事を表示

Goの構造体のレシーバを利用したらcannot define new methods on non-local type stringというエラーがでる

# はじめに

構造体をなんとなくで利用していてエラーが発生したのでまとめます
同じエラーがおきるようなことは少ないかもですが、起きたときにルールを知らないと時間を使ってしまいそうでした

# 問題

“`go:testdata.go
package testdata

func (u *User) CreateUser (user User) {
// ユーザー作成の処理
}
“`

このような`User`のレシーバーをテストデータを作成する箇所で作成したのですが以下のようなエラーが発生しました

“`
cannot define new methods on non-local type string
“`

# 解決方法

レシーバーを利用するときは`自パッケージ内で定義したtype`でなければならないというルールがありました
このコードでは関係ないところでレシーバーを使っていたのでエラーが発生しています

もしレシーバーを作成するなら`User`を定義していた`models`のパッケージのどこかに書く必要があったようです

# おわりに

まだまだ構造体やインターフ

元記事を表示

Gormで全レコード削除をしたが削除されなかった

# はじめに

いままで全レコード削除できていると思っていたコードが機能していなかったことで時間を取られましたのでまとめます
GORMを使い始めたばかりのときにつまづく箇所になりそうです

# 問題

以下のようなコードでユーザーデータの削除を行っていました

“`go:user.go
db.Delete(&User{})
“`

これですべてのユーザーが削除できていたと思っていたのですが、テストをした際にユーザーのメールアドレスのユニークバリデーションで引っかかってしまい、他のテストデータが削除できていないことが判明しました

# 解決方法

“`go:user.go
db..Unscoped().Where(1=1).Delete(&User{})
“`

として削除ができるようになりました

ポイントは2つで、全レコードを削除するには`Where`を使わないと削除ができないということ、`Unscoped`で物理削除を行うことでした

ここではWhere(1=1)で無理やりWhereを利用して全レコード削除をしています

とくに`Where`は知らないとつまづくポイントなの

元記事を表示

Goのテストでテストデータのレコードで重複が起きユニークバリデーションエラーが起きて失敗する

# はじめに

Goのテストを書くときにテストデータの挙動でかなり時間を使ってしまったのでまとめます

# 問題

テストデータをCreateUserで毎回同じユーザーを作成するようにしているのだが、なぜかメールアドレスのバリデーションエラーが発生してテストが失敗してしまう。

そして成功するときもあれば失敗するときもあるので挙動がよくわからなかったです

ユーザーは作成後(テスト終わり)に削除をしていました

“`
2022/09/05 08:07:38 /go/src/models/db_test_setting.go:50 Error 1062: Duplicate entry ‘test@sample.jp’ for key ‘users.email’
“`

# 解決方法

Goのテストは並列で実行されるためユーザー作成のタイミングが被ることが起こり得ました
そしてそのタイミングになぜテストが失敗になるのかを調べたところ、インサートに失敗した際に以下のようなハンドリングをしていました

“`go:user.go
if err != nil {
log.Fatal

元記事を表示

Goの構造体内関数を利用してオブジェクト指向っぽくAPIにリクエストする

# 概要

Goの構造体と関数の紐付けの仕組みを利用し、オブジェクト指向っぽくAPIにリクエストする。
この仕組みを利用することで、認証キーなどの共通の設定を、メソッドごとに引数で渡す必要がなくなり、よりシンプルにAPIリクエストをするコードが書けるようになった。

## 構造体と関数の紐付け

Goでは下記のように記述することで、構造体と関数を紐づけることができる。

“`go
package main

import (
“fmt”
)

type Person struct {
Name string
}

func (p *Person) Introduction() string {
return fmt.Sprintf(“私の名前は%sです”, p.Name)
}

func main() {
p := &Person{“たろう”}

fmt.Println(p.Introduction())
}

“`

`func (p *Person) 関数名 ~`と宣言すると、その関数を構造体に紐づいた関数として定義するこができ、その関数が構造体(`Person`)の

元記事を表示

整数型に ‘c’ が代入できるそれぞれの事情

# これは何?

https://qiita.com/Cowsisland/items/71248bdd081089b7ba09

という記事で

“`c:c
int a;
a = ‘c’;
“`

が問題なく動いている話や [素晴らしいコメント](https://qiita.com/Cowsisland/items/71248bdd081089b7ba09#comment-732ca0b2d7c2a7be908d) があって面白かったので、記事にしてみた。

# それぞれの事情

## C言語

C 言語の場合、そもそも `’c’` の型が `int` である。
なので

“`c:c
int a;
a = ‘c’;
“`

は、わりと面白くない。

Twitter 方面で、 `’c’` の型が `int` であることに疑問を抱いている方が散見されるので追記。

なぜそうなっているのかは知らないんだけど、C 言語では古来よりシングルクオートで囲まれたリテラルは `int` 型になっている。規格書にもそう書いてある。

古い C でも

“`c:c
printf( “sizeo

元記事を表示

Go [O1o1o0] 目指せ!第14回UEC杯コンピューター囲碁大会<本編>

# Step [O1o1o0g1o0] はじめに

? Step の変な数字の説明

? [電脳向量表記](https://qiita.com/muzudho1/items/fdbf31e41dd8c247081f)

? 練習編を読み終わってるものとする

? [Go [O1o1o0] 目指せ!第14回UEC杯コンピューター囲碁大会<練習編>](https://qiita.com/muzudho1/items/cea62be01f7418bbf150)

? また、技術的でない内容を含むブログを別の場所に 開設する

? [目指せ!第14回UEC杯コンピューター囲碁大会☆(^q^)<その2>](http://grayscale2.dou-jin.com/go/%E7%9B%AE%E6%8C%87%E3%81%9B%EF%BC%81%E7%AC%AC%EF%BC%91%EF%BC%94%E5%9B%9E%EF%BC%B5%EF%BC%A5%EF%BC%A3%E6%9D%AF%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E

元記事を表示

バックグラウンドでの定期実行処理をゴルーチンで回す際の注意点

強化月間なので、今回もGoの記事を上げていきます。

https://qiita.com/official-events/ae80b010f51f7018891a

# はじめに

アプリケーションで長時間の処理を実行する際、以下のような処理を挟むことがあると思います。

– メイン処理途中に同時並行で定期的に流す処理(例:処理中ログの表示)
– メイン処理完了時に流す処理(例:完了ログの表示)

定期実行処理はメインの処理の裏で同時に流したいので別のゴルーチン内に実装しますが、気を付けないと**完了時処理より後に定期実行処理が流れてしまいます**。ハマるとたまにしか再現せず厄介なので、備忘録としてまとめました。

# 定期実行処理でハマったこと

以下の3つの処理を流すことを考えます。

– メインとなる処理(長時間かかる)
– メイン処理中に流す定期実行処理(処理中ログの表示)
– メイン処理完了時処理(完了ログの表示)

定期実行処理はメイン処理をブロックしてほしくないのでゴルーチンに追い出します。

“`go
func longProcess() {
// 実際には何か長い

元記事を表示

Go言語のチャネルで空のデータを送受信したいときは構造体を使うと良い

## 概要

Go言語において空の構造体は**メモリサイズが0**であるという特徴があります。
この特徴を利用したい瞬間がいくつかあるため紹介しようと思います。

## 並行処理

Go言語で並行処理を行う際、とくにデータを送る必要はないが信号を送りたいというタイミングがあります。
そういった場合には空の構造体が良く使われます。

“`go
package main

import “fmt”

func send(ch chan<- struct{}) { ch <- struct{}{} ch <- struct{}{} close(ch) } func main() { ch := make(chan struct{}) go send(ch) for c := range ch { fmt.Println("receive : ", c) } } ``` 当然、空の構造体を送受信しているだけなので出力は下記のようなものです。 ```text {} {} ``` 空の構造体はメモリサイズが0であるためパフォーマンス的にも優れています。 ## ma

元記事を表示

RailsコードをGoで書き直して、FFIを使ったらメモリリークした話

先日、[速度改善のためRailsコードをGoで書き直して、FFIを使ってみた](https://qiita.com/t_mapico/items/9eadf5bee5561c3fb589) という記事を書いたのですが、
このコードがメモリリークを起こしてしまいました。。

golang初心者のため、C.Cstringがgoのメモリ解放の管理から外れているいうことを把握していませんでした。。

“`
return C.CString(string(resultJSON))
“`
となっているとこを deferで解放するようにしました。

“`
ret := C.CString(string(resultJSON))
defer C.free(unsafe.Pointer(ret))

return ret
“`

メモリリークしないか1時間くらい動かしてチェック

“`

end_time = (Time.now + 60 * 60).to_i

while (Time.now.to_i < end_time) # ObjectSpaceはデフォルトが

元記事を表示

[Go]テストコード

# 1. テストコードの実装に必要なこと
– テストコードを書くファイルについて
– ファイル名: “xxx_test.go“とする
– ファイルの配置: テスト対象関数のパッケージのディレクトリ
– テストコードファイルの記述
– “package“ディレクティブでテスト対象関数のパッケージを指定
– 標準出力のテストの場合
– 対象関数に対するテストは、引数なしの“ExampleXxx“という名前の関数で記述する
– 標準出力以外のテストの場合
– “import“ディレクティブでテスト“testing“パッケージを指定
– 対象関数に対するテストは、引数が“t *testing.T“である“TestXxx“という名前の関数で記述する

# 2. テストコードの実装
## 2.1. 前提
以下のような構成・内容のモジュールが存在するとして、各関数に対してテストコードを実装する場合を例にする。

**ディレクトリ・ファイル構成**
“`
go_test_code

元記事を表示

Four keys を計測する CLI ツールを作った

# はじめに

Four keys とはソフトウェア開発の生産性を測定するのに利用される以下の4つの指標のことである([参考](https://www.devops-research.com/quickcheck.html))。

– デプロイ頻度(Deployment Frequency) ソフトウェアのデプロイ頻度
– 変更リードタイム(Lead time for changes) ある変更をソフトウェアに適用してから、その変更がリリースされるまでの時間
– 障害修正時間(Time to restore) ソフトウェアに障害が発生してから、その障害が修正されるまでにかかった時間
– 障害率(Change failure rate)ソフトウェアのデプロイのうち障害が発生したデプロイの割合

これらの指標を簡易に測定するための CLI ツールを作成した。

https://github.com/hmiyado/four-keys

この記事では、この CLI ツールについて紹介する。

# 使い方

## インストール

[Releases](https://github.com/hm

元記事を表示

はじめてのGo Modules

初めてGoの開発案件にアサインされたのですが、前担当から引き継いだGoのバージョンが1.10なのに対して今回の開発では1.18だったので色々戸惑いました。
その際Go Modulesって何?となって調べたので備忘録。

# Go Modules
– Go1.11以降で利用できる依存パッケージ管理ツール。
– go mod init [モジュールパス] と go mod tidyでgo.modとgo.sumを作成してソースコード内でimportに記載してる外部パッケージのダウンロードと依存関係の処理を行ってくれる。
– Go1.10まではGOPATH モード (GOPATH mode)でコード管理を行なっており、コード管理とビルドをGOPATHで指定されたディレクトリ下で行っていた。Go1.11以降はモジュール対応モード (module-aware mode)を使用することで任意のディレクトリでコード管理とビルドが行えるようになった。

## 前提
– Go 1.18
– 環境変数GO111MODULEは on 又は未指定
– MacOS Monterey 12.5.1

#

元記事を表示

wfs – Go で書き込み可能な io/fs

## wfs とは

[jarxorg/wfs](https://github.com/jarxorg/wfs) で開発している Go標準 の io/fs を拡張したライブラリです。 現在は以下のファイルシステムをサポートしています。

– osfs
– memfs
– s3fs
– gcsfs

## 開発の動機

Go で S3 や GCS を使うほとんどのプロジェクトで、クラウドストレージにアクセスするためのインタフェースを新しく定義し、開発用にローカルファイルシステムの実装、テスト用にメモリ上での実装をして切り替えれるようなコードを書いてきました。

Go1.16 から登場した io/fs は今のところ読み取り専用で、書き込みについては [proposal: io/fs: add writable interfaces](https://github.com/golang/go/issues/45757) などで議論されていますが簡単には進まなそうです。

その Issue でも紹介されている afero や billy は非常に優秀ですが S3 に対応していなかったりして微妙

元記事を表示

Goの構造体をJSON形式で出力するいくつかの方法

## はじめに

Goの構造体をJSON出力する方法をまとめてみました。

### 検証方法

以下のようなPerson構造体をJSON出力していきます。

“`go
type Person struct {
Name string
Age int
gender string
}
“`

また、JSON出力した結果を見やすくするために、`Mrashal`ではなく`MrashalIndent`を使ってフォーマットしたものを出力するようにしています。

“`go:main.go
package main

import (
“fmt”
“encoding/json”
)

func main() {
p := Person{
Name: “Mike”,
Age: 20,
gender: “male”,
}

m, _ := json.MarshalIndent(p,””,” “)
fmt.Println(string(m))
}
“`

## 方法1: そのままMarshalする

まずは、特に何もせずにそのまま出力すると以下のような

元記事を表示

OTHERカテゴリの最新記事