Go関連のことを調べてみた2021年07月14日

Go関連のことを調べてみた2021年07月14日

gormとタグの指定

# 概要

Go言語にて、gormを利用してみました。
構造体を利用してORマッピングを行うことができます。

gormでのモデルの宣言は以下。

“` golang
import (
“gorm.io/gorm”
)

type User struct {
gorm.Model
Name string
}
“`

gorm.Modelをフィールドに持つことで、自動的に
“`created_at“`,“`updated_at“`,“`deleted_at“`,“`id“`フィールドを付与してくれます。この場合、主キーは自動的に“`id“`になります。

## タグでの指定
データベースの構造に対応して、各フィールドの設定を変更したい場合、タグを利用します。

“` golang
type User struct {
gorm.Model
ID int `gorm:”column:_id”`
Name string `gorm:”primaryKey column:user_name”`

元記事を表示

Golang には enum がないらしい

https://qiita.com/ikngtty/items/ad135599a2f92e6035fa

自分だったらこうするかなー、というのをやや冗長めに書いてみた。元記事で指摘している欠点を完全には解消できていないんだけどね。

### 使い方:

“`go
hoge := enum.SeasonValueOf(“ほげ”)
fmt.Printf(“‘ほげ’ は ‘%s’ の季節です。\n”, hoge.Ja())

fmt.Println(“——————–“)
w := enum.SeasonValueOf(“WINTER”)
fmt.Printf(“‘WINTER’ は日本語だと ‘%s’ です。\n”, w.Ja())
fmt.Printf(“‘WINTER’ は英語ならば ‘%s’ です。\n”, w.En())
fmt.Printf(“‘WINTER’ の次の季節は ‘%s’ です。\n”, w.Next().En()+”(”+w.Next().Ja()+”)”)

fmt.Println(“——————

元記事を表示

AtCoder Beginner Contest 197 ~Goの練習~

# [A問題](https://atcoder.jp/contests/abc197/tasks/abc197_a)

## 考察

文字列の二文字目以降をスライシングし、その後ろに文字列の一文字目を付け足して実装する。

## 文法

実装時にGoでは2通りのパターンが生まれると思う。

1パターン目は`s[1:]+string(s[0])`とする場合。Pythonの場合は一文字を切り出してもstringなので、このような書き方をすると思う。

2パターン目は`s[1:]+s[:1]`とする場合。文字列のスライシングではstring型のままなので、明示的な型変換の必要のないこちらを競プロでは採用するべきだと思う。

“`go
package main

import (
“bufio”
“fmt”
“os”
)

func main() {
scin := bufio.NewReader(os.Stdin)
prout := bufio.NewWriter(os.Stdout)
defer prout.Flush()

// code
var s string

元記事を表示

Google Cloud Storage を使用した分散ロックはどのように実装されているのか?

次の記事を読んでどのように実装しているのだろうと疑問に思い調べた結果を残しておきます。

https://cloud.google.com/blog/ja/products/storage-data-transfer/implementing-leader-election-google-cloud-storage

以下、本文中では Google Cloud Storage を GCS と表記しています。

## 調査対象

軽く調べたところ冒頭の記事で紹介されていた [hashicorp/vault](https://github.com/hashicorp/vault) 内のパッケージ以外にも類似機能を提供している OSS があったのでそちらも調べてみました。

### mco-gh/gcslock

https://github.com/mco-gh/gcslock

Go で実装されたライブラリとコマンドですがシェルスクリプト実装も公開されています。

mco-gh/gcslock は GCS が備えている [世代番号と前提条件](https://cloud.google.c

元記事を表示

Cloud Tasks API は context に設定したタイムアウトが 30 秒より大きいとエラーになる

[googleapis/google-cloud-go](https://github.com/googleapis/google-cloud-go) を使用して [Cloud Tasks API](https://cloud.google.com/tasks/docs/creating-appengine-tasks#go) の `CreateTask()` 実行したところ 30 秒より大きいタイムアウトは設定できないというエラーメッセージ (`The deadline cannot be more than 30s in the future.`) が返ってきたので調べてみました。

## 同じ問題に遭遇した例がないか探す

エラーメッセージで調べたところ次の Issue が見つかりました。
(クローズされていますが内容を見る限りでは未解決のままです)

https://github.com/googleapis/google-cloud-go/issues/1577

個々のリクエストでタイムアウトを指定したつもりはなかったのですが context に設定したタイムアウトが 30

元記事を表示

[Go] YAMLファイルを埋め込み構造体に読み込む

以前、Go言語でYAMLファイルを埋め込み構造体に読み込もうとした際に、JSONを読み込むのと同じように実装したらうまく読み込めなかったことがあった。
その時調べた内容をまとめておく。

# 結論

このようなYAMLファイルがあった場合

“`yaml
# tmp.yaml
wheels: 4
tons: 10
“`

下記のように構造体の埋め込みフィールドに`inline`タグをつけることで埋め込み構造体に読み込むことができる。

“`go
package main

import (
“fmt”
“os”

“gopkg.in/yaml.v2″
)

type Car struct {
Wheels int `yaml:”wheels”`
}

type Truck struct {
// 埋め込み のフィールドに ‘inline’ タグをつける
Car `yaml:”,inline”`
Tons int `yaml:”tons”`
}

func main() {
truck := Truck{}
b, _ := os.ReadFile(“tmp.

元記事を表示

AtCoder Beginner Contest 198 ~Goの練習~

# 感想

今回は時間がなかったので、内容があまり充実していません。

# [A問題](https://atcoder.jp/contests/abc198/tasks/abc198_a)

## 考察

$i,n-i$で$i \geqq 1$となるように配れば良いので、$n-1$通りが答え。これを出力する。

## 文法

特になし。

“`go
package main

import (
“bufio”
“fmt”
“os”
)

func main() {
scin := bufio.NewReader(os.Stdin)
prout := bufio.NewWriter(os.Stdout)
defer prout.Flush()

// code
var n int
fmt.Fscan(scin, &n)
fmt.Fprintln(prout, n-1)
}

“`

# [B問題](https://atcoder.jp/contests/abc198/tasks/abc198_b)

## 考察

本解説とは異なる方法。

左側に0を付け足すのでは

元記事を表示

【Go】入門(構造体と関数を紐付ける)

Goで構造体と関数を紐付ける方法についてのメモです。

# Goで構造体と関数を紐づける方法

Goでは、class内にメソッドを定義できません。
では、どのように構造体ごとの関数を定義するのか?

“`go
package main

import “fmt”

type Human struct {
Name string
Age int
}

func (h Human) addAge(i int) int {
return h.Age + i
}

func main() {
// インスタンス生成
hoge := Human{
Name: “hoge”,
Age: 20,
}

fmt.Printf(“%#v \n”, hoge)
hoge.Age = hoge.addAge(1)
fmt.Printf(“%#v \n”, hoge)
}
“`

つまり、構造体と関数の紐付けはこのようになります。

“`go
type Human struct {

元記事を表示

Prismaの基本操作(MySQL CRUD処理)

#本記事の内容
TypeScriptやGo言語をサポートしているPrismaの説明です。MySQLのCRUD処理に関した記事となります。
※TBLの作成方法は[マイグレーション編](https://qiita.com/kouji0705/items/945baaeab0a476550c40)を参考にしてください。

#基本情報

更新対象TBL(マイグレーション編で作成済)

![スクリーンショット 2021-07-11 17.01.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/cc33ba59-3684-7f08-9001-6bf50443e481.png)

ディレクトリ構成

“`
~/develop/study/starter $ tree -I node_modules
.
├── package-lock.json
├── pack

元記事を表示

Googleカレンダーで予定を作成したら、別アカウントのカレンダーに「ブロック」予定を作成する

個人用のGoogleカレンダーに予定を登録→平日なら内容に応じて前後30分増やして会社のカレンダーにブロック予定を作成、などを行います。[^zapier]
Google Calendar APIの[Go client library](https://pkg.go.dev/google.golang.org/api/calendar/v3)とApp Engineを主に用いて構築します。
内容をまとめたリポジトリはこちら:

https://github.com/shiraily/gcal-sync

# この記事について

記事内のコードは説明のための部分的なコードなので、エラー処理など完全なものはリポジトリを参照ください。
また、以下を前提として進めます。

– GCP projectが作成済み。以下を利用
– App Engine
– Cloud Scheduler
– Firestore
– Go / Google Cloud SDK

# 事前の設定

### Google Calendar APIの有効化

GCPでAPIを有効化します。[コンソール

元記事を表示

AtCoder Beginner Contest 199 ~Goの練習~

# 感想

今回から[作成したテンプレート](https://qiita.com/DaikiSuyama/items/f82d26399a49eb121004)を利用して問題を解くことにしたが、エディタの補完が突如として効かなくなったのであまり速くならなかった。

また、だいぶGo言語には慣れてきた気がするので、Web開発の勉強にできるだけ時間を割きたいと思い始めた。

# [A問題](https://atcoder.jp/contests/abc199/tasks/abc199_a)

## 考察

$A^2+B^2

元記事を表示

競プロ用テンプレート(Go)

# 前書き

入力の高速化用のコードとそれに付随してimportするパッケージを併せたものをテンプレートとして本記事にまとめます。

また、普段使っているPythonやC++とは異なり、パッケージが充実しているわけではないので、随時必要な関数などを追記する予定です。

# コード

“`go
package main

import (
“bufio”
“fmt”
“os”
)

func main() {
scin := bufio.NewReader(os.Stdin)
prout := bufio.NewWriter(os.Stdout)
defer prout.Flush()

// code
}
“`

元記事を表示

AtCoder Beginner Contest 209 ~Goの練習~

# 感想

今回もリアタイで参加することはできなかった。

E問題とF問題が知識がないとできないようだったのできつかった。

ただ、そもそも集中して解こうとしていなかったので、そもそも解く姿勢に問題がありそう。

# [A問題](https://atcoder.jp/contests/abc209/tasks/abc209_a)

## 考察

$a$以上$b$以下の整数の個数を出力する。

$b

元記事を表示

GoでファイルをZIP圧縮するWebAssemblyを実装してみた

## はじめに
最近、仕事で`Go`を書き始めたので、勉強がてらファイルをZIP圧縮する`WebAssembly`を実装してみました。
ソースコードは、[こちら](https://github.com/imunew/file-archive-wasm) で公開してます。

## やったこと
ローカルのファイルを選択して、「Archive」ボタンをクリックすると、`WebAssembly` 側でファイルをZIP圧縮し、ダウンロードリンクを生成します。

[![Image from Gyazo](https://i.gyazo.com/858ed4928ae9bb853d818bbf0b433275.gif)](https://gyazo.com/858ed4928ae9bb853d818bbf0b433275)

## もう少し詳しく
処理のフローをざっくり説明すると、以下のようになります。

– `WebAssembly`を読み込む
– 「Archive」ボタンをクリックしたときに、`javascript`側でファイルを読み込み(`readAsDataURL`)
– `base64`で

元記事を表示

Goによる競プロライブラリ~Union-Find木~

# 内容

自身の記事である[競プロのライブラリ整理~Union-Find木~](https://qiita.com/DaikiSuyama/items/444e409423bd1b4b83d7)のPythonコードを元に、GoによってUnion-Find木を実装しました。参考になれば幸いです。

# コード

下記が実装になります。

“`go
/*
n: 要素数
parent[i]: iの親となる要素
siz[i]: iを含む素集合のサイズ
group[i]j: 代表元をiとする素集合に含まれる要素の配列j
*/
type UnionFind struct {
n int
parent []int
siz []int
group map[int][]int
}

/*
コンストラクタ
任意のiについて、parent[i]=i、siz[i]=1、として初期化
group[i]jは空のmapとして初期化
*/
func NewUnionFind(n int) *UnionFind {
uf := new(UnionFind)
uf.n = n
uf.

元記事を表示

AtCoder Beginner Contest 201 ~Goの練習~

# [A問題](https://atcoder.jp/contests/abc201/tasks/abc201_a)

## 考察

題意の通りの操作をする。

与えられる数列を`sort.Slice`により並び替え、並びかえた数列が等差数列であるかを問題文中の通りに判定すれば良い。

## 文法

### ソートについて

コメント欄にてご指摘をいただいたため、追記します。

下記のソートのコードは

“`go
sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) ``` このように書き換えることができるようです。 ```go sort.Ints(a) ``` ## コード ```go package main import ( "bufio" "fmt" "os" "sort" ) func main() { scin := bufio.NewReader(os.Stdin) prout := bufio.NewWriter(os.Stdout) defer prout.Flush() v

元記事を表示

GoでTestifyでテストする際のassertとrequireの違い

### `assert`か`require`か。

どちらも同じに見えるが、動きが少し異なる。

結論から言うと、
* **`assert`は途中でFailしてもテストは続行する**が、
* **`require`は途中でFailしたらそこでテスト関数を抜ける**。

`require`は、テストに必要な前提条件などの確認で使い、
`assert`は目的のテストのために使うとよさそう。

#### 使い分けの例:
`Foo()`をテストしたいが、`Foo()`を実行するためにフォルダが必要な場合。

“`go
func TestFoo(t *testing.T) {
err := mkFooDir()
require.NoError(t, err)

actual := Foo()
assert.Equal(t, fooExpected(), actual)
}
“`

### サンプルコード
https://play.golang.org/p/EAbcXAenWI3

“`go
package main

import (
“testing”

元記事を表示

AtCoder Beginner Contest 203 ~Goの練習~

# [A問題](https://atcoder.jp/contests/abc203/tasks/abc203_a)

## 考察

$a=b,b=c,c=a$のいずれかが成り立つかそれ以外かで条件分岐を行えば良い。

## 文法

4つの条件分岐なので、下記のようにswitch文を用いて実装すると良い。

“`go
package main

import (
“bufio”
“fmt”
“os”
)

func main() {
scin := bufio.NewReader(os.Stdin)
prout := bufio.NewWriter(os.Stdout)
defer prout.Flush()

var a, b, c int
fmt.Fscan(scin, &a, &b, &c)
switch {
case a == b:
fmt.Fprintln(prout, c)
case b == c:
fmt.Fprintln(prout, a)
case a == c:
fmt.Fprintln(prout, b)
default:

元記事を表示

goenvを卒業しよう

# はじめに
Go言語のversionを使い分ける際に`goenv`を利用している方は多いと思います。
このエントリでは`goenv`を使わずに複数versionを切り替える方法をまとめます。

# 簡単3ステップ

[Goのプロジェクト構成の基本](https://zenn.dev/nobonobo/articles/4fb018a24f9ee9) の方法で実施します。

最初にOSのパッケージマネージャーでGoをインストールします。
この時は version を気にしなくて良いです。
後述の手順で利用する version を導入するためにだけインストールします。

+ on Ubuntu: (WSL2でも同様)

“`shell:install.sh
sudo apt install golang-go
“`

続いて`GOPATH`, `PATH` を設定します

“`shell:env.sh
export GOPATH=$HOME/.go
export PATH=$GOPATH/bin
“`

続いて使いたいGo versionをインストールします。

“`shell

元記事を表示

Goをherokuでデプロイした時にエラー: code=H10 desc=”App crashed”が出た

#背景
**やりたいこと:**
・Goで立てたサーバーをLINEmessagingAPIに結びつけてBOTを作ろうとしている
・LINEmessagingAPIのWebhookに貼るためにherokuでサーバーをデプロイする

**現状:**
・localhostでは問題なく画面表示できている(エラーの出力等はなし)

・デプロイの方法はherokuの[公式ドキュメント](https://devcenter.heroku.com/ja/articles/getting-started-with-go?singlepage=true)を参照してください

#エラー:Application error

“`
$ git push heroku master
“`
上記コードでデプロイしようとしたところ

![Heroku_Application_Error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1728773/a3bb63ab-d07d-5720-5629-b614700fdd8c.p

元記事を表示

OTHERカテゴリの最新記事