- 1. 【Golangエラー】type does not implement as method has a pointer receiver
- 2. 【Golang】8 バイトの []byte を uint64 に変換する( 64ビット長のバイト・スライスをintに変換したい)
- 3. sqlmock + gormでDB周りのテストを書く
- 4. GoのORM入門(go-pg ハンズオン)
- 5. Goで2次元mapをgenericsで良い感じのデータ構造にする
- 6. goのgenericsチュートリアルを試してみる
- 7. Ubuntuに好きなGoのバージョンをaptでインストールする
- 8. IdeaPad Duet ChromebookにGo言語をインストールする
- 9. 【go】インストールしたライブラリで command not foundになるときの対処法
- 10. 【Golang】echoサーバーでcsvファイルをstructにする&structをcsvにする
- 11. AWS Cognito でLINEログインのボットリンク機能を使う
- 12. 私家版 Go言語のポイント
- 13. goで変数をtemplateの名前として利用する
- 14. ポータブルでクールなCI/CD開発ツールのDaggerを試してみたら最高に良かった!
- 15. Go + MySQL で BULK INSERTしてみた
- 16. goのポインタ
- 17. Magicodeという簡単に稼げるエンジニア向けブログサービスを作ったので使って欲しい
- 18. TCPによるソケットプログラミング
- 19. gin favicon
- 20. 【Go】protoc-gen-validateを含めたprotoファイルでコード出力時に`protoc-gen-go: invalid Go import path`が発生
【Golangエラー】type does not implement as method has a pointer receiver
interfaceを受け取る関数に構造体を渡そうとしたところ、エラーが出てきてちょっとつまづいたのでメモです。
`hello world`を出力するシンプルなプログラムを見ながら挙動を確認します。## うまくいかない場合
以下のコードだと `Type does not implement ‘sampleInterface’ as the … has a pointer receiver`というエラーが出てうまくいきません。
“`main.go
package mainimport “fmt”
type sampleInterface interface {
DoSomething()
}func interfaceReceiverFunc(si sampleInterface) {
si.DoSomething()
}type sampleStruct struct {}
func (s *sampleStruct) DoSomething() {
fmt.Println(“hello world”)
}func main() {
s :=
【Golang】8 バイトの []byte を uint64 に変換する( 64ビット長のバイト・スライスをintに変換したい)
> Go 言語(以下 Golang)で、`make([]byte, 8, 8)` で作成した 8 バイトのスライスを uint64 に変換したい。
[「`golang “[]byte” uint64 変換`」でググって](https://www.google.com/search?q=golang+cap%E4%BB%98%E3%81%8D+%22%5B%5Dbyte%22+%E7%B5%90%E5%90%88+%E9%80%A3%E7%B5%90)も、逆の `uint64` から `[]byte` に変換するものや、`int32` のリトルエンディアン だったり、符号あり前提のものばかりだったので、自分のググラビリティとして。
## TL; DR (今北産業)
– `encoding/binary` の Golang 標準パッケージを使う。
– `binary.BigEndian
sqlmock + gormでDB周りのテストを書く
## sqlmockとは
Goのテスト用のDBを用意しなくてもSQLドライバのような振る舞いをしてくれるモックのライブラリ
## パッケージのバージョン
“`:go.mod
gorm.io/driver/postgres v1.3.4 // indirect
gorm.io/gorm v1.23.1 // indirect
“`## 困ったこと
gorm.io/driver/mysqlのv1.3.2では正しく動作しない。v1.0.3では正しく動作する。
Where(“id=?”, 1) ではなく Where(“id = ?”, 1)を記述する。https://github.com/Watson-Sei/go-sqlmock-gorm
## 解決フロー
このような困った仕様に気づくために記事を見るだけでなく実際に動くコードをGitHubからcloneしてきてコードを色々変えて試してみることがとても大切だと感じた。Versionも確認すること。
## 実際のコード
“`go
package d
GoのORM入門(go-pg ハンズオン)
## go-pgのチュートリアル
### 開発環境の説明
“`markdown:開発環境
PC:Mac(CPUはintel製)
Go:1.17.6 ←Goのver大事。versionは1.16以降をインストールしてください。
開発エディタ:Visual Studio Code
go-pg: v10.10.6
“`“`shell:ディレクトリ構成
~/go/src/go_pg_lesson $ tree -I “.data|schema”
.
├── db
│ └── migrations
│ ├── 000001_create_users_table.down.sql
│ └── 000001_create_users_table.up.sql
├── docker-compose.yml
├── go.mod
├── go.sum
└── main.go2 directories, 6 files
“`## Lesson1: CRUD処理の基本操作
### 1. TBLの準備“`shell:TBL作成
CREATE TAB
Goで2次元mapをgenericsで良い感じのデータ構造にする
# TL;DR
[Githubのコード](https://github.com/yut-kt/gostruct/blob/main/map.go)読んでみてください.# 前書き
趣味でgolangのHMM音声認識エンジンを作っている際,bigramやtrigramの確率保存で複数キーからなる連想配列が欲しくなりました.
パッと思いつくのは二次元mapかなと思いましたが,良い感じのものないかなと探していました.記事を探していると[[Goで多重連想配列]](https://qiita.com/daigo2010/items/d46975ad6decd8578c45)があり,確かに何も考えずに二次元のmapにアクセスするとヌルポになりそうということが分かりました.
少し処理が煩わしいのでもっと綺麗に作れないかなと思い探していると,[[Goで多次元マップ(複数のキーからなるマップ)を実現したいときにはどうするか]](https://qiita.com/ruiu/items/476f65e7cec07fd3d4d7)という記事を見つけてカッコイイと思いました.そこで実際どれが良いかな
goのgenericsチュートリアルを試してみる
## 使用環境
– Macbook Pro 16inch (Intel)
– Goland IDE## 準備
1. go 1.18.1を[こちらから](https://go.dev/doc/install)インストール
1. Goland IDEのプロジェクトの言語バージョンを1.18に設定(GOROOTとGOPATH両方を設定しました、正しいかはわかりません)
1. go.modも1.18のものを生成するGoland IDEを2022バージョンにしないと赤い波線のエラー表示が出ますが、コードは普通に動きます。
## 実際のコード
こちらは[tutorial](https://go.dev/doc/tutorial/generics)ページから取得したものです。
“`main.go
package mainimport “fmt”
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}func SumFloats
Ubuntuに好きなGoのバージョンをaptでインストールする
## golang-backportsをapt repositoryに追加する
“`
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
“`## バージョンを指定してgoをインストールする
“`
sudo apt install golang-1.18
“`## 設定
“`bash:~/.profile
GOPATH=~/go
GOROOT=/usr/lib/go-1.18PATH=$GOROOT/bin:$PATH
“`
IdeaPad Duet ChromebookにGo言語をインストールする
# パッケージを最新化する
インストールされているパッケージを最新化します。
“`
$ sudo apt clean
$ sudo apt update
$ sudo apt full-upgrade -y
“`# 必要なパッケージをインストールする
必要なパッケージをインストールします。
“`
$ sudo apt install build-essential -y
$ sudo apt install exuberant-ctags
“`# Goをダウンロードする
IdeaPad Duet ChromebookのCPUはARMです。
[Goのダウンロードサイト](https://go.dev/dl/)からLinux ARMのファイルをダウンロードします。
ここでは、go1.18.1.linux-arm64.tar.gzをダウンロードしました。# Goの環境変数を設定する
.profileに以下を追加します。
“`
export GOROOT=/usr/local/go
export GOPATH=${HOME}/go
export PATH=${GOROOT
【go】インストールしたライブラリで command not foundになるときの対処法
# 対処法
“`
export PATH=$PATH:$HOME/go/bin
“`
でパスを通す# 問題
“`
go get -u github.com/swaggo/swag/cmd/swag
“`
をインストールして、
“`
swag -v
“`
をすると
“`
command not found
“`
エラーになる
【Golang】echoサーバーでcsvファイルをstructにする&structをcsvにする
## はじめに
Golangサーバーを新規に構築する中で、CSVファイルの入出力を汎用的にした備忘録です。
GitHub: https://github.com/Sunochi/go_echo_server## TL;DR
SJIS形式をUTF8形式に`transform.NewReader`で変換して、`csvutil`で構造体にマッピングする。
1行ごとに処理をせずに、全行一気に処理している。
膨大な行のcsvには向かないため、もしバッチ処理などで使用する場合は今後の修正にご期待ください。https://github.com/Sunochi/go_echo_server/blob/master/internal/csv/csv.go
### csv読み込み
“`csv.go
func ReadFile(fh *multipart.FileHeader, s interface{}) {
csvFile, err := fh.Open()
if err != nil {
log.Println(“csv file open error:”, err)
}
AWS Cognito でLINEログインのボットリンク機能を使う
# 背景
AWS Amplify で作成するアプリに**LINEログイン**を組み込み、ボットリンク機能(LINEログイン時に公式アカウントを友だちに追加する機能)を有効にしようと思ったのですがすんなりと行きませんでした。
[ウェブアプリにLINEログインを組み込む | LINE Developers](https://developers.line.biz/ja/docs/line-login/integrate-line-login/)
[LINEログインしたときにLINE公式アカウントを友だち追加する(ボットリンク) | LINE Developers](https://developers.line.biz/ja/docs/line-login/link-a-bot/)調査したところ、Cognito側でLINEの認可URLにパラメータを追加することができないようでした。詳しくは下記の記事を御覧ください。
[Amazon CognitoではLINEログインのボットリンク機能は…使えません!](https://zenn.dev/kecy/articles/7e8648dd
私家版 Go言語のポイント
「[Welcome to a tour of Go](https://go-tour-jp.appspot.com/list)」のポイントを個人的にまとめたものになります[^1]。
[^1]:単なる個人的まとめなので、ポエム扱いにしています。
:::note
演習問題も自分なりの回答を記載してありますが、Go初心者ですので、あくまで参考程度です。なお、各演習の下の「Go Playground」リンクをクリックすると、Playgroundへ飛んで、実際に動かすことができる、はずです[^2]。
:::[^2]:これはいつまで保存されるのだろう?]
## 基本
### パッケージ/変数/関数
#### Package
+ Goプログラムはパッケージで構成される
+ mainパッケージが起点となる
+ パッケージ名はパスの最後の部分となる(math/rand→rand)#### Import
+ importは単独でもグループでも書くことができる
“`go :group-import.go
import(
“fmt”
“math”
)
“``
goで変数をtemplateの名前として利用する
# 実現したいこと
goで使用可能な`text/template`のテンプレート名として変数名を使いたいと思います。しかしそのまま利用しようとする以下のコードはPanicが発生してしまいます。
“`golang:失敗例
package mainimport (
“os”
“strings”
“text/template”
)var TMPL = strings.Trim(`
{{- /* []string expected */}}
{{- define “sasakuna”}}
{{- range $i, $text := . }}
{{$i}}: {{$text}}
{{- end }}
{{- end }}
`, “\n”)func main() {
tmpl := template.Must(template.New(“”).Parse(TMPL))
tmpl = template.Must(tmpl.Parse(`{{ template .Name .Data}}`))tmpl.Execute(os.Stdout, struct {
Na
ポータブルでクールなCI/CD開発ツールのDaggerを試してみたら最高に良かった!
# Daggerとは
公式サイトは以下です。
https://docs.dagger.io/
公式サイトによるとDaggerはCI/CDのためのポータブルな開発ツールとされています。
Daggerを使うメリットは以下です。括弧の中は筆者の意見/解釈です。
– CI/CDのパイプラインを一度書いておけば、どこでも同じパイプラインが実行できる (GitHub ActionsやCircle CIなどのツールによる記述の違いをある程度気にしなくて良くなりそう)
– CIツールのロックインを防ぐことができる (Github Actionsにインシデントが発生したらリリースが止まってしまう、みたいなことが防ぎやすくなる)
– CI/CDパイプラインのデバグを容易にする (ローカルでもCI環境を容易に構築できるので、リモートにいちいちpushしないと挙動が分からないとかいうことがなくなりそう)# とりあえずやってみる
## インストール
“`bash
❯ brew install dagger/tap/dagger❯ type dagger
dagger is /usr/l
Go + MySQL で BULK INSERTしてみた
# はじめに
Go で MySQL を操作する処理を書いているときに、BULK INSERT したいと思うときがありました。
日本語だと、外部パッケージに頼らずに BULK INSERT するための情報があまりなかったので、記事で残そうと思います。念の為の説明ですが、BULK INSERT とは、複数レコードを一回のINSERTで作成することを言います。
# 結論(コード)
早速ですがこちらが実装したコードです。
“`main.go
package mainimport (
“database/sql”
“fmt”
“log”_ “github.com/go-sql-driver/mysql”
)var DB *sql.DB
// DBと接続
func init() {
// databaseはあらかじめ作成しておく
dsn := “root:root@(127.0.0.1:3306)/test?interpolateParams=true”var err error
DB, err = sql.Open(“mysql”, dsn)
if er
goのポインタ
## ポインタ
– ポインタを渡すというのは、変数の内容を渡すのではなく、変数のメモリの値を渡すという意味
– なので、渡された関数などで、値の変更が合った場合は、渡された関数の外であってもそのポインタを参照すると値は変わっている
– ポインタではない通常の変数のわたし方の場合は、変数のコピーが渡されるため、関数内で値が変わった場合、変数が渡された関数の中と外でその変数を参照しても値は変わっている“`golang
package mainimport “fmt”
// ポインタ
func pointer(x *int) {
*x += 1
fmt.Println(“ponter func: “, *x)
}// ポインタではない
func nopointer(x int) {
x += 1
fmt.Println(“nopointer func: “, x)
}func main() {
z := 2
pointer(&z)
fmt.Println(z)fmt.Println(“————“)
y := 2
nopoi
Magicodeという簡単に稼げるエンジニア向けブログサービスを作ったので使って欲しい
https://jp.magicode.io/
# Magicodeとは?
QiitaさんやZennさんのようなエンジニア向けのブログサービスです。Magicodeという名称は,magicとcodeを組合せた造語です。基本的にはマークダウンで自分のブログが書けるサービスですが,特殊な機能が以下の4つほどあります。# 機能1. ブラウザ上でコードを実行できる
ハリーポッターの新聞は動きますよね。そんな感じでMagicodeの記事も動きます。この機能はMagicodeという名称の元にもなっています。PythonやGo, Rustほか10程度の言語のランタイムにブラウザから接続できます。投稿者は,直感的なエディターを用いてコード動かしながら記事を作成することができます。さらに,読者も投稿された記事のコードを自由に編集しオンデマンドで実行することができる(編集内容は元の記事には反映されません)ので,コードの挙動を確認しながら記事を読むことができます。
// go run client.go 127.0.0.1:10000
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, “Usage: %s host:port “, os.Args[0])
os.Exit(1)
}
service := os.Args[1]
// ソケットの作成 & 接続相手のIPアドレスとポート
gin favicon
https://github.com/thinkerou/favicon
こちらを元にしました。“`golang
package middlewaresimport (
“bytes”
“fmt”
“io/ioutil”
“log”
“net/http”
“os”
“path/filepath”“github.com/gin-gonic/gin”
)// パスの区切り文字にはos関係なくスラッシュで渡す。
func ServeFavicon(path string) gin.HandlerFunc {
// “/”区切りのパスをosの区切り文字でのパスに変換。
path = filepath.FromSlash(path)
// 空文字でないandOSの区切り文字でないなら
if len(path) > 0 && !os.IsPathSeparator(path[0]) {
// 作業ディレクトリを取得
wd, err := os.Getwd()
// 作業ディレクトリの取得に失敗したら終了
if err != nil {
【Go】protoc-gen-validateを含めたprotoファイルでコード出力時に`protoc-gen-go: invalid Go import path`が発生
## 概要
GoのgRPCで、バリデートを実装する際に便利なのが、[protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate)です。[【Go】gRPCのリクエストバリデータを自動生成する](https://note.com/scg_tech/n/nb12a33bfd391)の記事で紹介されている通り、protoファイルでバリデートの定義を設定することで、バリデートのコードを自動生成してくれます。
今回はprotoc-gen-validateを含めたprotoファイルで、コード出力時に`protoc-gen-go: invalid Go import path`というエラーが発生したので、対応方法などをメモ書きします。## 事象発生時の状況
エラーが発生したprotoファイルは以下の通りです。
なお、使用したProtocol Buffersのバージョン`3.19.4`はです。
“`proto:src/proto/authenticationUser.proto
syntax = “proto3”;