- 1. Go言語がMethodでSliceをどう渡しているか覗いてみる
- 2. Goでバブルソート
- 3. Go言語 再帰を使用したフィボナッチ数
- 4. Firestoreをサーバサイドで使うTips
- 5. [翻訳] Golang におけるinterface 実装のベストプラクティス
- 6. 【Go, FileServer】画像の配信
- 7. 競プロ落とし穴 #1 SetでDFS
- 8. Go言語 無名関数の書き方
- 9. golangci-lint: exhaustivestruct
- 10. Go言語 ゴルーチン select
- 11. 【GitHub】Goのインデントがおかしい問題を解決する
- 12. Rocky Linux 8.4にGo環境をインストール(Linux)
- 13. golangにおける関数の引数
- 14. 【Go, go-cmp】子インスタンスで持つ値の並びを気にせずに比較したい
- 15. 【Docker】1分でローカルにGoの環境構築をする
- 16. Go言語 チャネル
- 17. Goのshadowingでハマる前にVSCodeの設定を見直すべし
- 18. GoでMarkdownからExcel試験書を作成するソフトを作った
- 19. Go言語製Let’s Encryptクライアントlegoをライブラリとして使う
- 20. ubuntuでgo関連のパッケージをインストールした時のメモ
Go言語がMethodでSliceをどう渡しているか覗いてみる
# どんな記事?
https://pkg.go.dev/container/heapGoでの優先順位付きキューの実装を見ていて、
「あれ、なんでこのmethodはポインタ渡して、こっちはそうじゃないんだろう」
と思ってしまったので自分用に整理してみるよ日本語だと変数の渡し方を値渡し、参照渡し、参照の値渡しとかって呼ぶけど、英語の方がかっこいいのでcall-by-value(値渡し), call-by-reference(参照渡し), call-by-sharing(参照の値渡し)って呼ぶことにする
ちなみにcall-by-valueで渡すvalueがreferenceだとcall-by-sharingって呼ばれるらしい
https://stackoverflow.com/questions/13899171/does-call-by-sharing-and-call-by-reference-differ-only-while-multithreading
# Sliceの1要素を変更する
sliceの要素に変数を代入する場合の違いをみていこう
## call-by-re
Goでバブルソート
最近またアルゴリズムの勉強を始めようと思い、まずはバブルソートを作ってみました。以前はこういう系はPythonでやってたんですが、最近Goの勉強もしてるのでGoで作ってみました。
こちらのオンラインエディタが勝手にフォーマットもしてくれて便利でした。
https://go.dev/play/## コード
“`go
package mainimport “fmt”
func main() {
numbers := [10]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}switched := true
for maxIndex := len(numbers) – 1; switched && 0 < maxIndex; maxIndex-- { switched = false for i := 0; i < maxIndex; i++ { left := numbers[i] right := numbers[i+1] if left > right {
numbers[i] = right
nu
Go言語 再帰を使用したフィボナッチ数
## 再帰
ある処理内部で、再びその処理自身を呼び出すような処理。## フィボナッチ数
2つ前の項と1つ前の項を足し合わせていくことでできる数。
自然界に多く見られる、数学的規則性。## Code
“`Go
var fibonacci func(n int) <-chan int // 何番目を求めるかを定義 fibTarget := [5]int{10, 15, 20, 25, 30} // フィボナッチ数を求めるための無名関数を格納 fibonacci = func(n int) <-chan int { result := make(chan int) // 無名関数によるゴルーチン go func() { // チャネルを閉じるための予約 defer close(result) // 2以下の場合は必然的に1 if n <= 2 { result <- 1 return } // 再帰により、n-1番目を求める f1 := <-fibonacci(n-1) // 再帰により、n-
Firestoreをサーバサイドで使うTips
# はじめに
Firestore、便利ですよね。大好きなGoogle Cloudプロダクトのひとつです。
ネイティブモードで利用して、**Web or モバイルアプリからmBaaS的に使うのが鉄板**だと思います。https://firebase.google.com/products/firestore/?hl=ja
ですが例えば**バッチジョブでデータを洗い替えたりする場合**等、サーバから直接触りたくなる状況もちょくちょくあるかと思います。
直近、サーバからFirestoreを触る機会がそこそこあったので、その中で得た備忘録的なものをまとめました。
**サンプルコードはGo**ですが、他の言語でも参考になる部分も多いかと思います。
思いつき次第随時更新いたします??# Tips一覧
## 1. ローカル環境からFirestoreを利用するFirestoreを組み込んだサーバアプリケーションをローカルで開発する場合、直接開発環境のFirestoreに繋ぎ込む方法と、Firestoreエミュレータを利用する方法があります。
### 開発環境のFirestoreに直
[翻訳] Golang におけるinterface 実装のベストプラクティス
この記事は [Best Practices for Interfaces in Go](https://blog.boot.dev/golang/golang-interfaces/) を翻訳した記事になります。
誤訳がある可能性があるため、リンク先の元記事をあらためて参照お願いします。## Golang におけるinterface とは何か
ほかのtype が実装できるカスタムtype のこと
これによって高い抽象度を得ることができる
他のtype が全てのメソッドを実祖した時に実装できる
## interface のベストプラクティス
そもそも綺麗なインターフェースを書くのは難しい
シンプルなコードもすぐに複雑になる
下記の3点を守れば綺麗なままでいられる
– interface は小さく作る
– interface には知識を入れない
– interface をclass のように扱わない### interface は小さく作る
本記事に置いて最重要なトピック
interfaceはアイデアやコンセプトを表すための最小の必要な振る舞いの定義を意味している
[HTTP Pa
【Go, FileServer】画像の配信
サーバ上に保存してある画像を各クライアントのブラウザに配信をするため、FileServerを利用した。
# 前提
“`plantuml@startuml
title フローは以下のようなものを想定
skinparam responseMessageBelowArrow true
autonumber
クライアント -> サーバ: ユーザ情報取得API Request
クライアント <-[#0000FF]-- サーバ: ユーザ情報の中に画像パス(/image/profile/1.jpg)を含んだJSONをResponse クライアント -> サーバ: 画像URL(https://hoge.jp/image/profile/1.jpg) Request
クライアント <-[#0000FF]-- サーバ: 画像データ Response @enduml ``` クライアントでは、ユーザ情報取得APIで返却されたJSONの中にある画像PathからURLを作りsrcに入れる ```html
競プロ落とし穴 #1 SetでDFS
# 競プロ落とし穴シリーズ
シリーズと書いてるけど多分これが初回で最終回:hugging:
競プロの問題を解いていてつまづいたところをメモしていくよ# 今回解いていた問題
https://atcoder.jp/contests/abc198/tasks/abc198_d出現する文字列(たかだか10種類)について全探索を行って条件を満たす解を探す問題
以下では簡略化したコードで考えていくよ
# 間違ったコード
“`golang
func AssignWithSet(N int) {
set := make(map[int]struct{})
for i := 0; i < N; i++ { set[i] = struct{}{} } ret := make(map[int]int) used := make(map[int]bool) for v := range set { ret[v] = -1 } scnt := 0 var DFSWithSet func(int) DFSWithSet = func(num int) { if num
Go言語 無名関数の書き方
Go言語の無名関数の記事が少ないので、ここでいくつか例を上げたいと思います。
## 環境
go 1.18## 例1 : 即時実行
“`go:input
package mainimport “fmt”
func main() {
// 無名関数
func() {fmt.Println(“Welcome! to Go Lang”)
}()}
“`“`terminal:ouput
Welcome! to Go Lang
“`
## 例2 : 変数に代入してから実行
Go言語では無名関数を変数に割り当てる事ができます。
無名関数を変数に割り当てると、その変数は関数型となり、関数をコールするようにその変数をコールする事ができます。
“`go:input
package mainimport “fmt”
func main() {
// 変数に無名関数を割り当て
value := func() {
fmt.Println(“Welcome! to Go Lang”)
}
value()}
“`“`terminal:ou
golangci-lint: exhaustivestruct
備忘録。
構造体のフィールドが全部初期化されているかどうかをチェックしたい場合は[exhaustivestruct](https://github.com/mbilski/exhaustivestruct)が便利。
exhaustivestructを有効化した上でstruct-patternsに構造体が [Path#Match](https://pkg.go.dev/path#Match) に合致するように記載する。
struct-patternsはパッケージ名も含められるので別パッケージで同名の構造体があっても対応できる。ハマったポイントとして、struct-patternsに指定するのはチェックしたい構造体が定義されているパッケージおよび構造体名を指定する必要がある点。
勘違いしてチェックしたい構造体が呼び出されているパッケージ名を指定しようとしていた。“`go
package exampleAtype Target {
Hoge string
}package main
func main() {
t := Target{}
}
“`
上記の場合、
Go言語 ゴルーチン select
## select
複数のゴルーチンからの、チャネルを介した値受け渡しを実現させるための構文
selectを使用することにより対象のチャネルからピンポイントで値を受け渡せる。## Code
“`Go
// ある数以上の素数を、1つ求める関数
func primeRoutine(targetLine int, primeChan chan int) {
fmt.Printf(“%d Line Target Goroutine Wake UP \n”, targetLine)
i := 0
for {
// 値のインクリメント
i++
// 素数チェック
if checkPrime(i) && targetLine < i { fmt.Printf("%d Line Target Goroutine Shut Down \n", targetLine) // チャネルにデータ送信 primeChan <- i return } } } // メイン関数 func main() { // 求める素数の基準値 targetLin
【GitHub】Goのインデントがおかしい問題を解決する
## 原因
GitHub上でデフォルトのタブサイズが8になっているから。
つまり、`1tab = 8 半角スペース`という状況です。## 解決策
1. `https://github.com/settings/appearance`へ行きます。
1. Tab Sizeを4にします。
## 余談
chromeの拡張機能だったり、クエリパラメータでタブサイズを変える方法がググると出てきたのですが、最近デフォルトの設定になったんですかね?
Rocky Linux 8.4にGo環境をインストール(Linux)
linuxのOSにGo環境をインストールする手順です。
今回はRocky Linux 8.4を使用しています
※Centos8系は同手順で同様にインストールできる認識手順
cd /usr/local
バージョン15をインストール(2022年4月時点の最新バージョンは17)
wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.15.2.linux-amd64.tar.gz
rm -rf go1.15.2.linux-amd64.tar.gz
バージョン確認
go version
go version go1.15.2 linux/amd64環境変数を設定
vi .bash_profile
export ROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$ROOT/bin#設定後読み込み
golangにおける関数の引数
“`golang“`を勉強していて以下のような書き方を見て、よく分からなかったので調べてまとめてみようとおもいます
“`
type Item struct{
name string
price init
}func itempointer(i *Item){
fmt.Println(*i)
}
“`“`golang“`にはポインタの概念が存在していて、関数の引数の型に値型や、ポインタ型を指定できます。
上のコードのように記述することで、構造体の要素の型を**コピー**しているんです。短いですが、以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。【参考資料】
https://go.dev/doc/faq#Pointers
https://yyh-gl.github.io/tech-blog/blog/go-always-passing-by-value/
【Go, go-cmp】子インスタンスで持つ値の並びを気にせずに比較したい
SortSlicesだと子インスタンスで持つ値がバラバラの場合、無視することが出来ないが[Transformer](https://pkg.go.dev/github.com/google/go-cmp/cmp?utm_source=godoc#Transformer)だと出来る。
NumSlice構造体で持つNumsの順番がバラバラな構造体を作る。
“`golang
func TestSortSlice5(t *testing.T) {type NumSlice struct {
Id int
Nums []int
}type Compare struct {
NumSlice NumSlice
}v1 := &Compare{
NumSlice: NumSlice{Id: 1, Nums: []int{1, 2, 3, 4, 5}}, // 昇順
}
v2 := &Compare{
NumSlice: NumSlice{Id: 1, Nums: []int{5, 4, 3, 2, 1}}, // 降順
}opts :
【Docker】1分でローカルにGoの環境構築をする
# 本記事について
Go言語の環境をdockerを用いて構築します。dockerさえインストールしてれば秒で環境構築できます。
パッケージ管理にGo modulesを使っています開発環境用です。
## 環境構築
### Dockerfileを用意する
“`Dockerfile:Dockerfile
FROM golang:1.16-alpineWORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod downloadCOPY *.go ./
RUN go build -o /docker-gs-ping
EXPOSE 8080
CMD [ “/docker-gs-ping” ]
“`参照: [docker docs](https://matsuand.github.io/docs.docker.jp.onthefly/language/golang/build-images/)
### 必要ファイルを用意する
まずはGo modulesを開始するコマンド
“`
$ go mod init ex
Go言語 チャネル
## チャネル
チャネルとは、平行実行されているGoroutineから値を受け渡す機能である。## Code
“`Go
// ある数以上の素数を求める関数
func primeRoutine(targetLine int, primeChan chan int) {
i := 0
for {
// 値のインクリメント
i++
// 素数チェック
if checkPrime(i) && targetLine < i { // チャネルにデータ送信 primeChan <- i //[キーポイント] } } } // メイン関数 func main() { // 求める素数の基準値 targetLine := 100000 // チャネルの作成 primeChan := make(chan int) // ゴルーチンで素数を求める go primeRoutine(targetLine, primeChan) // チャネルからデータを受信 primeResult := <-primeChan //[キーポイント]
Goのshadowingでハマる前にVSCodeの設定を見直すべし
# GoにおけるShadowとは?
こちらの記事に詳しいですが、要は**変数の再定義**のことです。
予期せぬバグの温床になるので気をつけましょう。https://yourbasic.org/golang/gotcha-shadowing-variables/
`go vet –shadow GO_FILE`
で検知できるのですが、IDEでリアルタイムに検知したいところですよね。というわけで以下です。
# VSCodeで–shadow機能を有効化する
UserでもWorkspaceでもどちらでも良いので、`settings.json` に以下を追記しておきましょう。
“`json
{
“gopls”: {
“analyses”: {
“shadow”: true
}
}
}
“`# Golandで–shadow機能を有効化する
この方の記事に詳しいです。
https://zenn.dev/uuusu/articles/6554631b4c08ba
GoでMarkdownからExcel試験書を作成するソフトを作った
## 入力

[このmd文書](https://github.com/botanic7arc/markdown2excel/blob/master/src/test.md)を入力すると
## 出力

こうなります。(横が入りきらなかったため、縮小して表示しています)
## ソース
https://github.com/botanic7arc/markdown2excel/tree/master/src
##
Go言語製Let’s Encryptクライアントlegoをライブラリとして使う
ピリカではほとんどのサービスでGCPやAWSが発行するHTTPS証明書を使っていますが、見える化ページと呼ばれる、自治体や企業など、一定の範囲内でのごみ拾い活動を集約しているサービスで使っているワイルドカード証明書はLet’s Encryptで発行しています。
Let’s Encryptで証明書発行するためのクライアントとしては標準のcertbotの他にもいろいろなものがあります。
個人的に、[lego](https://github.com/go-acme/lego)を気に入って使っています。お気に入りポイントはこんな感じです。– Go言語で作られていて、Pythonの言語環境に依存せずに使える
– いろいろなDNSサービスに対応している
– コマンドラインがcertbotよりもわかりやすいコマンドとしてずっと使っていて、このコマンドを内部的に使用する形で証明書を自動更新をするCloud Runを作ろうとしていたのですが、改めてリファレンスを読んでいたところ[ライブラリとしても運用できる](https://go-acme.github.io/lego/usage/libra
ubuntuでgo関連のパッケージをインストールした時のメモ
## やりたかったこと
こちらのパッケージをubuntuのサーバーに入れようとしたhttps://github.com/prasmussen/gdrive
README.mdには、ソースからのインストールは下記のコマンドでやろうということだった
“`
go get github.com/prasmussen/gdrive
“`そうかgoがいるのか、と思いapt-getでgoをインストールした後に`go get`のコマンドを実行しようとしたらハマったのでメモ。
### 間違えた手順と発生したエラー
“`bash
sudo apt-get golang
go get github.com/prasmussen/gdrive
“`
でインストールしようとしたところ、`go get`のところでこんなエラーが
“`
package context: unrecognized import path “context” (import path does not begin with hostname)
“`どうやらバージョン問題っぽい。apt-getで入れると古い