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

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

Goの日時フォーマットあれこれ

# はじめに
Goの日付フォーマット、時間フォーマットは多言語と比べてユニークです。覚えるまでに少し時間がかかります。なので、ここでまとめてみました。

## 年
| 文字 | 解説 |出力例|
|:-|:-|:-|
|2006|4桁の年|2000, 2022|
|06|下2桁の年|00, 22|

~~~go
// 2022年の場合
fmt.Println(time.Now().Format(`2006`)) // 2022
fmt.Println(time.Now().Format(`06`)) // 22
~~~

## 月
| 文字 | 解説 | 出力例 |
|:-|:-|:-|
|2|1桁または2桁の数字|1, 2, …, 10, 11, 12|
|_2|1桁または2桁の数字。先頭は半角スペース埋め|1, 2, …, 10, 11, 12|
|02|2桁の数字。先頭は0埋め|01, 02, …, 10, 11, 12|
|Jan|省略した月名。大文字小文字を区別する。| Jan, Feb, …, Nov, Dec|
|January|フルテキストの月名。大文字

元記事を表示

[Golang] [GCP] grpc-gatewayがbackend serverにX-Cloud-Trace-Contextヘッダーを渡す方法

## やりたいこと

`grpc-gateway`がHTTP/1.1で受け取ったリクエストヘッダー`X-Cloud-Trace-Context`の情報を
BackendへgRPCで通信するときにも伝搬してBakend側で使用したい。

## 想定しているアーキテクチャ

![grpc-gateway_grpc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335866/7a600ef0-fd84-84be-a782-072fd3b592a8.jpeg)

## grpc-gateway側の設定

muxを作成する際に、http headerを伝播するオプションをセット。
`runtime.WithIncomingHeaderMatcher()`を設定しない場合、header情報は伝搬されない。

“`go
mux := runtime.NewServeMux(runtime.WithIncomingHeaderMatcher(matcher))
“`

`matcher`で伝搬したいheader

元記事を表示

Go言語で配列・スライスをなんでも受け取れる関数を作る

## はじめに

`[]int` でも `[]string` でも、どのような型の配列でも、どのような型のスライスでも、引数として受け取れる関数を作りたいことがありました。
作ろうとしたら一筋縄ではいかなかったので、その方法を書き留めておきます。

## 環境

“`zsh:terminal
% go version
go version go1.17.6 darwin/amd64
“`

## 失敗例

はじめに、引数の型に `interface{}` を使うとなんでも受け取れるので `[]interface{}` を使えばどのような型の配列・スライスでも受け取れるだろうと思い、以下のコードを書きました。

“`go:main.go
package main

import (
“fmt”
)

func printElements(array []interface{}) { // []int や []string など、配列・スライスならなんでも受け取りたい
for _, e := range array {
fmt.Println(e)

元記事を表示

オブジェクト詰め替え対策の一つ — interface利用(golang)

ORM層とdomain層とデータ受け渡しをする場合、オブジェクト詰め替えが頻繁に発生することで、以下のデメリット・不便が感じている:

– コーディング作業がめんどくさい
– 詰め替え漏れ故のバグ
– 詰め替え処理自体の処理コストはどうかとの心配

これで試した対策の一つは interface利用のことです。
詳細はあとで…

元記事を表示

【Go】gormでテーブル名と構造体の名前が違う時のtips

Go難しいです。gormは「なんでやねん」と思うことが多いです。
元Railsエンジニアには早すぎた技術なのかもしれません?

[Many To Many](https://gorm.io/ja_JP/docs/many_to_many.html)周りの公式の記事が少しわかりにくくて、tipsを書いておきます

# Many To Many (many2many)
gormでは`Preload()`する際に、構造体のフィールドのタグ(`reflect.StructTag`)を仕込むことで、中間テーブルを簡単にORM側に理解させることができます。

## 普通の書き方
gorm内部的には、`Field`という構造体で`TagSettings map[string]string`で値を持っていて、全部大文字に変換してるので`map[MANY2MANY:many2many:user_languages]`という感じで保存してあります

“`go
// usersテーブル
type User struct {
ID uint
Languages []*Languag

元記事を表示

[Golang] [標準logライブラリ] GCPの構造化ログにX-Cloud-Trace-ContextのtraceIdをセットする

## やったこと

前回の記事で下記の課題があった。それを改善したのが本記事の内容。

> サービス運用では同時に複数のアクセスが考えられるため、traceId等でログを追跡できるようにする必要があります。アクセスがたまにしかないようなフェーズではいいかもしれないけど、X-Cloud-Trace-Contextを使用してリクエストとログを一意にできるようにすることは必須だと思うので今後やる。

https://qiita.com/t_morimori777/items/7040b6ea025db4e54630

## はてなブログに掲載しています。

https://moritomo7315.hatenablog.com/entry/go-traceid-logging

元記事を表示

Go の Gorm 使う

# はじめに

`Go`を勉強し始めたということで、`O/Rマッパー`も体験しておきます。

今回は、[Go で API 作る](https://qiita.com/pure-adachi/items/47dca38f5508c42f35b3)の続きとして、`Gorm`を入れて試してみたいと思います。

# 早速作ってみる

https://github.com/pure-adachi/go-sample-api-server

今回もこれをベースに組み込んでいきます。

[Go で API 作る](https://qiita.com/pure-adachi/items/47dca38f5508c42f35b3)の続きなので、API部分は`gin`を使います。
※`gin`の使い方は、上記Qiita記事で紹介しているので割愛します。

# Gorm を取得する

`Docker`で開発しているので、`docker compose`コマンドとなります。
`DB`は`PostgreSQL`を使ってみます。

“`sh
$ docker compose run –rm back go g

元記事を表示

goでutf8メールを送信する

Goでメールを送信することは簡単です。`net/smtp`の`SendMail()`で送信できます。しかし、これは平文の送信に限った話です。

マルチバイト文字である日本語を平文のまま送信してしまうと、メーラーによっては文字化けが発生します。よって、utf8エンコーディングしてから送信する必要が出てきます。

メールを送信するには、お決まりのインターネットメッセージフォーマットを守る必要があります。そこで決まっているのが、 [RFC2822](https://datatracker.ietf.org/doc/html/rfc2822) という文書です。ここで特に気にしないといけないのが、一行あたりの文字数です。翻訳してみると、

>There are two limits that this standard places on the number of characters in a line. Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 cha

元記事を表示

ポインタについて

最近Goを触り始めました。右も左も分からない状況ですが、今日学んだことをアウトプットしていきます。

## ポインタ
めちゃ大事そうだったのでまとめようとおもいます。まず、これを理解するためには**アドレス**を理解しなければなりません。
コンピュータにはメモリという作業場があって、変数はこのメモリに格納されているんですね。その格納されている場所をアドレスというんです。Goではアドレスをポインタと呼んでいます。
つまり、アドレス=ポインタ
実際にポインタを取得してみましょう
“`test.go
package main

import “fmt”

func main() {
name := “what is golang?”
fmt.Println(&name)
}

=> 0xc000042230
“`
Printlnの後に、**&変数名**と書くことでポインタを取得できます。
それでは今度はポインタを変数に代入してみましょう。

“`test.go
package main

import “fmt”

func main() {
name := “what is

元記事を表示

GoでSQLのSELECTをする

Goの標準パッケージを使ってデータベースに接続してSELECT文を実行する方法を調べたので、簡単にまとめる。

## 準備

### 1. パッケージのインポート
抽象的な操作を提供する標準パッケージの`database/sql`と、実際にMySQLに対する操作が実装されている`go-sql-driver/mysql`をインポートする。他のパッケージは必要に応じて。

“`go
import (
“database/sql”
“fmt”
“log”
“time”

_ “github.com/go-sql-driver/mysql”
)
“`

### 2. 結果を代入する変数の宣言

“`go
var (
id *int
name *string
)
“`

### 3. sql.DBオブジェクトの生成

使用するドライバやデータベースの認証情報を渡して`sql.DB`オブジェクトを生成する。この時点ではまだDBへのコネクションは作られておらず、コネクションは実際にクエリを発行する時に`database.sql`パッケージが勝手に生成・破棄してくれるらしい。

元記事を表示

[Go] “空構造体”の表し方

# はじめに結論
**空の構造体(struct)は、「struct{}」と表します。**
interface{}みたいなものですね。

空構造体は、
– 空の構造体は**メモリサイズが 0である**
– 空の構造体は**属性**を持たない
– 空の構造体は**同じアドレス**を示す

といった特性を持ちます。

# 構造体(struct)とは?
**「type [定義する名前] struct」** のように使用します。
“`go
// 「Person」という名前の構造体(struct)
// この場合、NameとAgeという「フィールド」を持っています。
type Person strcut {
Name string
Age int
}
“`
「フィールド」はpytonなどで使われるclassでいうところの、コンストラクタのようなものです。

そして、このフィールドを何も持たない、つまり”空”であるため、
“`go
struct{}
“`

この書き方で表せるのですね〜。

##### ちなみに使い方の実例はこんな感じです。
“`go
type (
Pe

元記事を表示

Btreeの実装例(golang)

#何が書いてあるか
BtreeのGoでの実装例。備忘録。

##

“`go
// 節・葉に持たせる機能のインターフェース
type Item interface {
Eq(Item) bool
Less(Item) bool
}
// インターフェースの実装
type Int int
func (n Int) Eq(m Item) bool {
return n == m.(Int)
}
func (n Int) Less(m Item) bool {
return n < m.(Int) } // 節・葉の構造 type Node struct { item Item left, right *Node } // 節・葉の作成 func newNode(x Item) *Node { p := new(Node) p.item = x return p } // 二分木 type Tree struct { root *Node } // 二分木の生成 func newTree() *Tree {

元記事を表示

漸化式アルゴリズムサンプル(golang)

#何が書いてあるか
漸化式のアルゴリズムのGo版。備忘録用。

## 適用ケース
N段の階段をA段飛ばし、B段飛ばしで登ったときの、各段ごとにとれる登るパターン数を計算する。 など
上記ケースでのコード例)

“`go
package main
import “fmt”
func main(){
dp:=make([]int,N+1)
dp[0]=1

for i:=1;i<=N;i++ { dp[i]=0 if i>=A {
dp[i]=dp[i]+dp[i-A]
}
if i>=B {
dp[i]=dp[i]+dp[i-B]
}
}
// ここから続く5行は、頂上手前で飛ばす段数よりも残り段数が少ない場合には、頂上に到達させるとする場合のルート数の計算。
end:=0
for i:=N-1;i>=N-A+1;i– {
end+=dp[i]
}
dp[N]+=end

元記事を表示

[Go] Structの子要素を親要素のポインタで変更できるのか

## はじめに
Structのポインタを渡して中身を変更するときに子要素のStructの中身も変更できるのか分からなかったので検証しました。

バージョン:Go 1.16

## 検証
“`go
package main

import “fmt”

type Child struct {
AAA string
}

type Parent struct {
BBB string
Child Child
}

func changeParent(p *Parent) {
p.BBB = “ccc”
}

func changeChild(p *Parent) {
p.Child.AAA = “ddd”
}

func changeChildDirect(c *Child) {
c.AAA = “eee”
}

func main() {
c := Child{
AAA: “aaa”,
}

p := Parent{
BBB: “bbb”,
Child: c,
}

fmt.Println(p)
// {bbb {aaa}}

change

元記事を表示

# 【Go】チョットわかるインタフェース

自分がインタフェースについて理解したことをまとめます。僕と同じ初学者の理解を手助けできればうれしいです。Gopher道場が提供してくれている動画やスライド、書籍「プログラミング言語Go」を参考にしています。

## 最初にこの記事の結論

以下のようになりました。タイトルの通りちょっとしかわかりませんでした。

> インタフェースの使い方はちょっと分かったけど、メリットを実感できる使い方まではわからなかった。
>

## はじめに用語を整理する

最初に用語を整理します。現時点は「へえ」くらいの温度感でいいと思うのでざっくり意味を理解することが大切だと思います。

| メソッド | レシーバと紐づけられた関数 |
| — | — |
| インタフェース | 抽象化を実現するメソッドの集まり |

## 前段階にメソッドの理解を深める

本題はインタフェースの理解を深めることですが、前段階としてメソッドの理解を深める必要があると感じています。以下はメソッドを使用した簡単なコードです。一緒に見ていきましょう。

“`go
package main

import (
“fmt

元記事を表示

デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239) 参戦記

# デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239) 参戦記

## [ABC239A – Horizon](https://atcoder.jp/contests/abc239/tasks/abc239_a)

2分で突破. 書くだけ.

“`python
from math import sqrt

H = int(input())

print(sqrt(H * (12800000 + H)))
“`

## [ABC239B – Integer Division](https://atcoder.jp/contests/abc239/tasks/abc239_b)

4分半で突破. 試したら Python の除算そのままであれってなった.

“`python
X = int(input())

print(X // 10)
“`

## [ABC239C – Knight Fork](https://atcoder.jp/contests/abc239/tasks/abc239_c)

9分で突破. 2点の周

元記事を表示

[Golang] enumを使いたい ~ structでも定数定義できるぞ

元々Javaエンジニアの私ですが、最近Goを趣味で使い始めたのでメモ程度に。
今回はJavaでよく使うenumをGoでもそれっぽく使う方法を残しておきます。

## まずは基本的な使い方
よくGoogleで検索して見かけるやつ

“`hoge1.go
package constant

// 自動で採番してくれる
const (
HOGE1_1_1 = iota // 0
HOGE1_1_2 = // 1
HOGE1_1_3 = // 2
)

// 1始まりにしたい
const (
HOGE1_2_1 = 1
HOGE1_2_2 = 2
HOGE1_2_3 = 3
)

// 文字列で定義したい
const (
HOGE1_3_1 = “hoge1”
HOGE1_3_2 = “hoge2”
HOGE1_3_3 = “hoge3”
)

// 基本型をベースにした独自の型で定義したい
type HOGE uint8
const (
HOGE1_4_1 HOGE = 1
HOGE1_4_2 HOGE = 2
HOGE1_4_3 HOGE =

元記事を表示

Ubnutu20.04.3 LTSにGo言語の開発環境を構築する (Golang + VSCode+Ubuntu)

今更ながら、Ubnutu20.04.3にGoをインストールします。

## インストールするマシンについて
### os情報

“`bash
user@machine:~/gotrain$ cat /etc/os-release
NAME=”Ubuntu”
VERSION=”20.04.3 LTS (Focal Fossa)”
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME=”Ubuntu 20.04.3 LTS”
VERSION_ID=”20.04″
HOME_URL=”https://www.ubuntu.com/”
SUPPORT_URL=”https://help.ubuntu.com/”
BUG_REPORT_URL=”https://bugs.launchpad.net/ubuntu/”
PRIVACY_POLICY_URL=”https://www.ubuntu.com/legal/terms-and-policies/privacy-policy”
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
`

元記事を表示

【Go】http.ResponseWriterのメソッドw.Header().Add()が効かない

http.ResponseWriterのメソッドHeader().Add()でヘッダーを追加したはずなのに、レスポンスのヘッダーを見ると付与されていない。

単純にw.Header().Addの前に、w.Writeを呼び出していたことが原因だった。順番を逆にすると、想定どおり動作する。

“`go:改修前
func(w http.ResponseWriter, _ *http.Request) {
w.Write([]byte(“Hello, world”))

w.Header().Add(“Access-Control-Allow-Origin”, “http://localhost:3000”)
w.Header().Add(“Access-Control-Allow-Headers”, “Content-Type, X-CSRF-Token”)
w.Header().Add(“Access-Control-Allow-Methods”, “POST, OPTIONS”)
w.Header().Add(“Access-Control-Expose-Headers”,

元記事を表示

[Golang] Cloud Runで構造化ログを出力できるように実装してみた

## やったこと

* goの標準log出力をGCPの構造化ログのフォーマットで出力するようにしてみた。
* Cloud Runにデプロイして確認してみたところ無事ログが各ログレベルで出力されるようになった。
* 標準logライブラリのファイル名表示などされなくなったが、ログの出力をgrepすれば調査はできるので一旦よしとします。

## 課題

* サービス運用では同時に複数のアクセスが考えられるため、traceId等でログを追跡できるようにする必要があります。アクセスがたまにしかないようなフェーズではいいかもしれないけど、`X-Cloud-Trace-Context`を使用してリクエストとログを一意にできるようにすることは必須だと思うので今後やる。
* Cloud loggingなどの仕組みをつかってERRORのログをSlackに通知する仕組みとか作ってみようと思います。

## 内容ははてなブログに掲載してます

https://moritomo7315.hatenablog.com/entry/golang-gcp-log-output

元記事を表示

OTHERカテゴリの最新記事