- 1. 一年目Rubyエンジニアが一から学ぶGo言語 ポインタ編
- 2. go mod tidyの役割
- 3. Goでヒストグラムを描いてみた
- 4. gqlgen v0.16.0 で generating core failed: unable to load github.com/[username]/gqlgen-todos/graph/model エラー
- 5. Go言語のバージョン管理ツール[goenv]の導入
- 6. Goの日時フォーマットあれこれ
- 7. [Golang] [GCP] grpc-gatewayがbackend serverにX-Cloud-Trace-Contextヘッダーを渡す方法
- 8. Go言語で配列・スライスをなんでも受け取れる関数を作る
- 9. オブジェクト詰め替え対策の一つ — interface利用(golang)
- 10. 【Go】gormでテーブル名と構造体の名前が違う時のtips
- 11. [Golang] [標準logライブラリ] GCPの構造化ログにX-Cloud-Trace-ContextのtraceIdをセットする
- 12. Go の Gorm 使う
- 13. goでutf8メールを送信する
- 14. ポインタについて
- 15. GoでSQLのSELECTをする
- 16. [Go] “空構造体”の表し方
- 17. Btreeの実装例(golang)
- 18. 漸化式アルゴリズムサンプル(golang)
- 19. [Go] Structの子要素を親要素のポインタで変更できるのか
- 20. # 【Go】チョットわかるインタフェース
一年目Rubyエンジニアが一から学ぶGo言語 ポインタ編
Webエンジニアとして実務でプロダクト開発に携わること約1年弱、バックエンドの技術としてはRuby(とRails)一本でやってきた私ですが、エンジニアとしてやっていくからには静的型付け言語の習得も必要だろうということでGoの学習を始めました。
そんな中でRubyには無かった機能や概念のうち、個人的に理解に時間がかかったものを備忘録も兼ねて整理していきたいと思います。
とりあえず第一弾ということで、今回はポインタについてです。# ポインタ事始め
最初に躓くと定番?のポインタです。Rubyでもポインタの概念が無いわけではないようですが、少なくとも私は今まで意識したことがありませんでした。
そもそもメモリやアドレスが何か?については、様々な記事でイラスト付きで分かりやすく図解されているため、ここでは割愛します。
私は下記の記事で理解を深めました。https://zenn.dev/ak/articles/1fb628d82ed79b#%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF
“`golang
var num int = 10
var ptr *i
go mod tidyの役割
[公式サイト](https://go.dev/doc/tutorial/getting-started)でgoの学習をしていてわからなかったことがあったのでメモ書きとしてまとめようとおもいます。
## go mod tidy
結論からいうと、モジュール管理していて使わなくなったり必要なくなったパッケージを削除するためのコマンドです。
実際に“`go mod“`コマンドを打って確かめてみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/69f3c0b7-0bd5-cf1a-bd6f-a9d533d02965.png)
「add missing and remove unused modules」と書かれています。
不足していたり、使われていないモジュールに良しなに対応してくれるコマンドみたいですね。
ちなみに、tidyは「几帳面」という意味なのでそれも覚えとくと役割も理解できると思います。短いですが、以上です。何か間違いがございましたら、ご教示いただ
Goでヒストグラムを描いてみた
こんにちは、wattakです。
[前回のGoCVの投稿](https://qiita.com/wattak777/items/5f961c47d33def14e36f) から間が空きましたが、画のヒストグラムを描いてみました。
## 考え方
### ヒストグラムの作成
なんてことはないです。
GoCV(OpenCV)が用意している CalcHist を呼ぶ、だけ。関数仕様は以下。
“`go
func CalcHist(src []Mat,
channels []int,
mask Mat,
hist *Mat,
size []int,
ranges []float64,
acc bool)
“`[GoCVの関数仕様](https://pkg.go.dev/gocv.io/x/gocv#CalcHist)
[OpenCVの関数仕様](https://docs.opencv.org/4.x/d6/dc7
gqlgen v0.16.0 で generating core failed: unable to load github.com/[username]/gqlgen-todos/graph/model エラー
## 要約
Go で GraphQL のサーバサイドのコードを生成してくれる [gqlgen](https://gqlgen.com/)。
2022/02/26 時点の最新版 v0.16.0 に Go のバージョン依存のバグがあり、go1.16 系の場合、公式サイトの [Getting Started](https://gqlgen.com/getting-started/) 通りにやるとエラーになる。
go1.17 系なら問題ない。go1.16 系で Getting Started 通りにやって
“`
go run github.com/99designs/gqlgen init
“`というコマンドを打ったとき
“`
generating core failed: unable to load github.com/[username]/gqlgen-todos/graph/model – make sure you’re using an import path to a package that exists
“`というようなエラーが出たら、生成された g
Go言語のバージョン管理ツール[goenv]の導入
## やること
Go言語のバージョン管理ツール [goenv](https://github.com/syndbg/goenv) を導入する
## 導入理由
プロジェクトによってGo言語のバージョンが異なったり、バージョンアップ対応する場合があると思うので、バージョン管理を行えるように導入する
## 環境
– OS: Ubuntu (18.04 LTS)
– Git
– Shell: bash or zsh**Ubuntu向けに記載しますが、 `apt` とか使わないのでMacでも手順同じはずです**
→調べたらMacは `brew install goenv` だけでもインストールできるらしい。## 導入手順
ホームディレクトリにgoenvをcloneする
“`sh
git clone https://github.com/syndbg/goenv.git ~/.goenv
“`goenvを読み込むためのPATHを設定する
“`sh
# bashの場合
echo ‘export GOENV_ROOT=”$HOME/.goenv”‘ >> ~/.bashr
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 mainimport (
“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 mainimport “fmt”
func main() {
name := “what is golang?”
fmt.Println(&name)
}=> 0xc000042230
“`
Printlnの後に、**&変数名**と書くことでポインタを取得できます。
それでは今度はポインタを変数に代入してみましょう。“`test.go
package mainimport “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]=1for 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 mainimport “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 mainimport (
“fmt