- 1. draw.ioを操作するライブラリをGolangで書いてみた
- 2. Go言語ginを用いたモジュラモノリス構造について
- 3. Goでのスクレイピングに使っていたgoqueryをcollyに置き換えてみた
- 4. [Go] time.Time が encode & decode で元に戻らないので、time.Timeの中を調べてみた
- 5. 【Go/Gin】ちゃんとセッションを消すログアウト
- 6. Golangで多言語対応ライブラリのようなものを作ってみた
- 7. プログラミング経験者へのGo入門
- 8. 【MEMO】Goで文字コードを自動判別してCSVを読み込む/文字コードを指定して書き込む
- 9. [Go]並行処理・ゴルーチン
- 10. [Go]プログラミングノート
- 11. [Go]個人学習のための環境構築
- 12. [Go]パッケージ・モジュールまとめ
- 13. GoのAPIサーバーの実行にAirを使っていたというお話
- 14. Goの構造体のレシーバを利用したらcannot define new methods on non-local type stringというエラーがでる
- 15. Gormで全レコード削除をしたが削除されなかった
- 16. Goのテストでテストデータのレコードで重複が起きユニークバリデーションエラーが起きて失敗する
- 17. Goの構造体内関数を利用してオブジェクト指向っぽくAPIにリクエストする
- 18. 整数型に ‘c’ が代入できるそれぞれの事情
- 19. Go [O1o1o0] 目指せ!第14回UEC杯コンピューター囲碁大会<本編>
- 20. バックグラウンドでの定期実行処理をゴルーチンで回す際の注意点
draw.ioを操作するライブラリをGolangで書いてみた
## 背景
+ 画面イメージをdraw.ioを作成し、仕様書に手で貼り付けるなど、面倒な作業があったので自動化したかった。
+ 自動化する中で、draw.ioを操作するライブラリを作る必要があった
+ Golangの実践の機会を増やしたかった
## 作ったもの
自動化まではまだ達成できていないが、draw.ioで使われるデータをいじれるようなライブラリを作った。
このライブラリを使うことで、draw.ioに自動で図形を挿入したり,draw.ioのライブラリを楽に作れるようになる。(使用例は別で記事を作成する予定)[Githubのリンクはこちら](https://github.com/capybara-alt/libdrawio)
“`golang:main.go
// drawioファイルをロードし、MxFile構造体にマッピング
mxfile, err := libdrawio.NewMxFile(“./mxfile_test_1.drawio”)
if err != nil {
t.Fail()
}// MxFile構造体のDiagramの値を
Go言語ginを用いたモジュラモノリス構造について
Go言語(gin)を用いたサーバを構築する際に、モジュラモノリス構造を実現するためのフォルダ構成等を試行錯誤した結果を示す。
モジュラモノリス構造は時が来た時にマイクロサービスへ簡単に切り出せるし、素晴らしいアーキテクチャですね(^_^)[こちら](https://github.com/tnakamura512/go-modular-monolith-base)にサンプルコードがあるのでそれをベースに..
# アーキテクチャ
サーバとしてはモバイルアプリから呼ばれるAPIサーバである。(Viewは存在しない)
今担当してるプロダクトに準拠してユーザ管理、メッセージ送信、歩数ランキング機能を保有しているものとする。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200860/bb7b8079-cffc-f518-b29c-0b532dba9918.png)
– User Model
– ユーザ登録、Tokenによる認証等、よくあるやつ
– Message Model
Goでのスクレイピングに使っていたgoqueryをcollyに置き換えてみた
# はじめに
以前,goqueryを用いて東京ドームのイベント情報を1日1回取得するLambda関数を実装してみたのですが,どうやら[colly](http://go-colly.org/)というライブラリが割といいという話を後になって知りました.
深夜テンションでライブラリを置き換えてみたのでその記録です.
日本語での情報が少ないため,go言語でスクレイピングをしたい方のお役に立てれば幸いです.goqueryで実装したときの記録:https://qiita.com/a_uchida/items/1cdd7a1a6003d8a93651
# colly vs goquery
## スター数
[![Star History Chart](https://api.star-history.com/svg?repos=gocolly/colly,PuerkitoBio/goquery&type=Date)](https://star-history.com/#gocolly/colly&PuerkitoBio/goquery&Date)collyのほうが急激に伸びていますね.という
[Go] time.Time が encode & decode で元に戻らないので、time.Timeの中を調べてみた
## time.Time を encode して decode しても元に戻らない?!
[`time.Time`](https://pkg.go.dev/time) の [gob](https://pkg.go.dev/encoding/gob) の encode / decode を試していて驚いたことがありました。以下の実行結果、みなさんわかりますか?
“`golang:main.go
package mainimport (
“fmt”
“time”
)func main() {
t1 := time.Now()
b, _ := t1.GobEncode()t2 := time.Unix(0, 0)
t2.GobDecode(b)t3 := time.Now()
t3.GobDecode(b)fmt.Printf(“t1: %s\nt2: %s\nt3: %s\n”, t1.String(), t2.String(), t3.String())
fmt.Printf(“t1 == t2: %t\n”, t1 == t2)
fmt.P
【Go/Gin】ちゃんとセッションを消すログアウト
この記事はGo言語、Ginフレームワークの、とくにgin-contrib sessionのログアウトについて、しっかりセッションを消す方法について書いています。
# 通説
gin-contrib sessionの扱い方を紹介している記事で、よくログアウト機能をこのように組み立てているものが主流になっています。“`go
func Logout(ctx *gin.Context) {
session := sessions.Default(ctx)
session.Clear()
session.Save()
}
“`
しかし、この方法ではブラウザ側ではセッションが残ったままになってしまいます。
セッションの内容がnilになっているかでセッションチェックを行っている場合はちゃんとログアウトできているような挙動をしますが、ブラウザの開発ツールでcookieのセッションが残っていることが確認できることかと思います。筆者はこれを悪用したログアウト状態のPOSTを受けました(笑)
# 解決法
[GitHubのissue](https://gi
Golangで多言語対応ライブラリのようなものを作ってみた
## 背景
+ Golangを学習中で、実践的なコードを書きたかった
+ JSONファイルでエラーメッセージなどを管理できると良さそうと考えた
## 作ったもの
作ったものは至ってシンプルで、JSONファイルを読み込み、キーを指定することで定義したメッセージを取得できる。 [Githubのリンクはこちら。](https://github.com/capybara-alt/msgutil)
“`json:en.json
{
“errors”: {
“validate”: {
“null”: “column.a cannot be null”,
“invalid-value”: “Column {{0}} must be {{1}}”
},
“login”: {
“fail”: “Login fail”
}
},
“info”: {
“login”: {
“success”: “Login success!!”
プログラミング経験者へのGo入門
## 対象者
Goやりたいですってなった時
「そうだ! [Go Tour](https://go-tour-jp.appspot.com/welcome/1)やろう!」
となる人はGo Tourやってください。他の言語でプログラミングしたことあって、Go気になってるって人向けです。
## 環境
– Mac
– Go1.18## 下準備
“`
go mod init github.com/yourname/example
“`## パッケージの作成
パッケージは他の言語でいうモジュールです。
今回は2×2行列を実装します。
2×2行列は4つの整数を持ち、積を計算する `Multiple` メソッドを持つものとします。“`
mkdir matrix
vim matrix/matrix.go
“`“`go
package matrixtype (
Matrix2D struct {
// a, b
// c, d
a, b, c, d int
}
)func New(a, b, c, d int) Matrix2D {
ret
【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 testdatafunc (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 mainimport (
“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() {
// 実際には何か長い