- 1. Goのhtml/templateやGinでコメント文を削除させずに出力させたい時
- 2. 【golang】ジェネリクスを使ったcsvファイル読み込み
- 3. Hugo ドキュメント (日本語訳) のテーマを変更し、公開し直しました
- 4. Go言語の「Print、Printf、Println」の使い分け
- 5. Go 副作用を期待して関数にSliceを渡す際の注意点
- 6. Goでの書式付き出力
- 7. goで特定のTestifyのテストをCLIで実行する例
- 8. 【Golang】ECDH 公開鍵から DH 鍵交換で共通鍵を作成する(ディフィー・ヘルマン鍵共有)
- 9. 【爆速】Go × Docker で構築したアプリを GitHub Actions を使って GCP Cloud Run にデプロイする方法
- 10. 【Go言語入門】Goのレシーバーとは?2種類のレシーバーを使い分ける方法
- 11. PythonとGoに漸化式を解かせて速度の比較
- 12. 借りたサーバーにGOをinstallした
- 13. ローカル(VirtualBox)でのGo実行環境構築
- 14. Go言語での並行処理と並列処理: ゴルーチンとチャネルの活用法
- 15. [Go言語] スライス初心者ガイド: 空のスライスとnilスライスを理解する
- 16. goのポインタがよくわからなかったのでchatGPTに質問してみた
- 17. TourOfGoをやってみた
- 18. ec2を再起動するたびに特定のコマンド実行
- 19. Go言語における並列処理について
- 20. 【随時更新中!】Go言語で標準入力から値の受け取り方
Goのhtml/templateやGinでコメント文を削除させずに出力させたい時
# はじめに
よくあるWebサイトのhtmlを覗くとコメント文が書いてあることがよくあります。
ですが、Goで書いたWebサーバーはテンプレートを通すとコメント文がすべからく削除されます。ブラウザ上では基本的に見ることは無いので高速化するのに助かる機能ですが….
他のWebサーバーで存在するのにGoには無いのが気持ち悪いのでコメントアウトを記述できるようにします(~~隠しAA書けないし~~
↓テンプレートに使うファイル
“`templates/index.html
(適当な内容)
{{““ | safeHTML}}
“`# html/templateのみの場合
“`main.go
package mainimport(
“html/template”
“log”
“net/htt
【golang】ジェネリクスを使ったcsvファイル読み込み
# 今回やること
今回は、csvファイルを読み込む時に
カラムの名称、数に関係なく構造体で取得できるように実装してみます。
※ Generics機能を使うので、goのバージョンは1.18以上である必要があります。# 実装の流れ
最終的なゴールは、抽象的な構造体(`CsvAbstract`)を作り、そこにcsvコンバート用のメソッド(`ConvertCsv`)を生やします。
呼び出し側は、自分の好きな構造体を`CsvAbstract`に当てはめて、`ConvertCsv`をコールするだけ。
`CsvAbstract`の`Data`プロパティを見て、先程当てはめた構造体のインスタンスが入っていれば完成。今回csv関連で使用するパッケージは、`github.com/jszwec/csvutil`です。
# 抽象化した構造体とジェネリクス関数を定義
ジェネリクス機能を使うことで、「型が異なるだけで同じ処理をもつ複数の関数」を「1つの関数」として定義することができます。
ジェネリクスを使用しない場合、csv読み込み処理を型の数分作ることになります。まずは、構造体を抽象化した`Cs
Hugo ドキュメント (日本語訳) のテーマを変更し、公開し直しました
Qiita の過去記事「[Hugo ドキュメント (日本語訳) を公開しました](https://qiita.com/juggernautjp/items/07496d0c2fa1f592f548)」にて、サイト公開の告知をしました。
しかし、後述のような問題点を解決するために、利用していた Hugo テーマを変更するとともに、ホスティングサービスを [GitHub Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages) から [Cloudflare Pages](https://www.cloudflare.com/ja-jp/products/pages/) に変更して、新しく公開し直しました。
新しいサイトは、以下の URL です。
– [juggernautjp.info](https://juggernautjp.info/)
## 旧公開サイトの問題点
この場合、[本家の Hugo ドキュメントサイト](https://gohug
Go言語の「Print、Printf、Println」の使い分け
## はじめに
標準出力の3つの関数についてのまとめ記事です。## fmt.Print
`fmt.Print`関数は、与えられた引数をスペースで区切って標準出力に出力します。最後に改行は追加されません。“`go
package mainimport “fmt”
func main() {
name := “Alice”
age := 30
fmt.Print(“Name:”, name, ” Age:”, age) // 出力: Name:Alice Age:30
}
“`## fmt.Printf
`fmt.Printf`関数は、書式付きの文字列と一緒に与えられた引数を標準出力に出力します。最後に改行は追加されません。“`go
package mainimport “fmt”
func main() {
name := “Alice”
age := 30
fmt.Printf(“Name: %s Age: %d”, name, age) // 出力: Name: Alice Age: 30
}
“`
Go 副作用を期待して関数にSliceを渡す際の注意点
## 概要
Goの sliceは参照渡しだがややこしい
– 前提として Goのsliceは一応**参照渡し**である
– 参照渡しなので、呼び出し先の関数内の更新は、呼び出し元に**反映される** (`sli[0] = “updated”` 等)
– しかし goの**組み込み関数** `append`を使った更新は呼び出し元に**反映されない**
– 理由は `append`による更新が、単なる変数の再代入で実現されているからである(`sli = append(sli, “appended”)` 等)
– このため呼び出し元とヒープで共有するメモリには一切変更が入らない## テストコード
下記のテストコードでは下記の 3種類の関数を呼び出し、呼び出し元への影響を確認している
– 変数の再代入による更新
– 組み込み関数 appendを用いた更新
– 参照に閉じた更新“`golang
import (
“github.com/stretchr/testify/assert”
“testing”
)func TestSlice(t *testing.T
Goでの書式付き出力
`%s`を使う
“`go
package mainimport “fmt”
func main() {
weather := “晴れ”
fmt.Printf(“今日の天気は%sです”, weather) // 出力結果:今日の天気は晴れです
}
“`整数の場合は`%d`を使う
“`go
package mainimport “fmt”
func main() {
month := 6
day := 19fmt.Printf(“今日は、%d月%d日です”, month, day)
}
“`
goで特定のTestifyのテストをCLIで実行する例
## 例
“`shell
go test \
-timeout 120s \
-tags mybuildtag \
-run ^Test_MyTestSuite$ \
-v -test.v \
github.com/my-org/my-project/mypkg \
-testify.m ^\(Test_MyFuncTest\)$
“`## ポイント
– `-testify.m …`フラグはパッケージより後に置く
– 正規表現の内容によっては必要に応じて中身をエスケープする
– ここでは`()`カッコはエスケープする## Story
### VSCodeのOutputに騙された
いつもVSCodeの`run test`をクリックしてテストを実行していましたが、CLIで実行したい場面があり、
VSCodeのOutputビューに出力されるコマンドをコピペしたところうまくテストが実行されず。
結局試行錯誤してヘルプ見て解決。### テストバイナリ向けのフラグはパッケージより後に渡す
ヘルプによれば、ビルドフラグ、
【Golang】ECDH 公開鍵から DH 鍵交換で共通鍵を作成する(ディフィー・ヘルマン鍵共有)
> Go 言語(以下 golang)で、[共通鍵暗号](https://ja.wikipedia.org/wiki/%E5%85%B1%E9%80%9A%E9%8D%B5%E6%9A%97%E5%8F%B7)用の**共通の秘密鍵を、お互いの公開鍵から作成したい**。
>
> つまり「相手の公開鍵」と「私の秘密鍵」をゴニョゴニョして作成された鍵が、相手も同じように「私の公開鍵」と「相手の秘密鍵」でゴニョゴニョして作成された鍵と同じであれば、2 人の共通の秘密鍵として利用できるということです。[GPG](https://ja.wikipedia.org/wiki/GNU_Privacy_Guard) で作成した鍵で [GitHub に登録できるアルゴリズム](https://docs.github.com/ja/authentication/managing-commit-signature-verification/checking-for-existing-gpg-keys)(RSA, ElGamal, DSA, ECDH,
【爆速】Go × Docker で構築したアプリを GitHub Actions を使って GCP Cloud Run にデプロイする方法
# はじめに
最近は Go でのバックエンド開発やインフラ周りも少しずつ触る機会が増えてきたので備忘録としてまとめてみました。## この記事で書くこと
– Go と Docker で作ったアプリを docker-compose で起動する方法
– 上記で作ったアプリを Github Actions 経由で Cloud Run にデプロイする方法## この記事で書かないこと
– Go言語の基礎
– Docker / docker-compose の基礎
– Github Actions の基礎## 事前準備
以下の項目は事前に設定しておいてください。
すでに登録済みの方はスルーでOKです。### GCPアカウントの作成
– Google Cloud の[公式サイト](https://cloud.google.com/)にアクセス
– ページ右上の [無料で始める] ボタンをクリック
– Google アカウントでログインしてください。もし Google アカウントをお持ちでない場合は、[アカウントを作成] ボタンをクリックして新しい Google アカウントを作成
– ア
【Go言語入門】Goのレシーバーとは?2種類のレシーバーを使い分ける方法
## はじめに
Goのレシーバーって何?って思った人に向けて、Goで使われるレシーバーという概念と、その中で重要な値レシーバーとポインタレシーバーの2種類の違いと使い分けについて解説します。
## Goの構造体について
まず前提として、Goでは構造体を使って複数のデータをひとまとめにできます。
構造体は次のように定義します。“`go
type Person struct {
Name string
Age int
}
“`
構造体のインスタンスは以下のように、初期化することができます。“`go
person := Person{Name: “taro”, Age: 42}
“`## レシーバーとは何か?
レシーバーとは、構造体に関連付けられた関数(メソッド)を定義するための機能です。
これにより、構造体のインスタンスに対して操作を行うことができます。
以下にコード例を示します。“`go
// 構造体の定義
type Person struct {
Name string
Age int
}// Person構造体
PythonとGoに漸化式を解かせて速度の比較
# はじめに
タイトルのまんま
簡単な3項間漸化式解かせて実行時間を取得
マークダウンで数列の表記できないから読み辛いかも# 前提
a1 = 2
a2 = 5
a(n+2) = 7a(n-1) – 12a(n)
のnに任意の正の整数を代入した時の値を取り出すちなみに一般項は
an = 3^n – 4^(n -1)
αで置換した二次方程式の解から等比数列作って導出このままだと扱いにくいから
a(n) = 7a(n – 1) – 12a(n – 2)
に変形
# ソースコード
まずはPython
“`
import sys
import time#再帰の回数をデフォルト1000より増やしておく
sys.setrecursionlimit(1500)def a(n):
if n == 1:
return 2
if n == 2:
return 5
else:
return 7 * a(n – 1) – 12 * a(n – 2)x = input(“入力して下さい。”)
#開始時刻取得
start = time.perf_counter()#
借りたサーバーにGOをinstallした
# 概要
https://lolipop.jp/にGOを使えるようにインストールしました。
## 追記
https://lolipop.jp/terms/prohibition/
ここに
– C言語などによるバイナリ実行ファイルのCGIの設置
がある事を完全に見落としていましたお試し期間中なのでphpを使っていきます。goを使いたいと思ったらサーバーに乗り換えようと思います
## 動機
サーバーエンジニアになろうとしているのに一回も自分のサーバーを使ったことがないのはどうかとお思い、無料期間で一旦試したかったからです。## 流れ
登録
↓
ssh接続
↓
goをinstall
↓
pathをつなげる### 登録
自分がとりあえず借りたのはここです。https://lolipop.jp/
### ssh接続
https://qiita.com/chihiro/items/c24fcbd82d1d8833e497
ssh接続をユーザーページで有効化してからじゃないとログインできないです。
### goを入れる
基本はここを参考にしました。
http
ローカル(VirtualBox)でのGo実行環境構築
# 作業環境
| 項目 | 値 |
| :—: | :—:|
| 仮想OS | Amazon Linux2 |
| CPU | 2 Core |
| 実装RAM | 2 GB |
| Disk | 25 GB |# 必要なツール
* SSH接続できるもの(Teratarm,Putty,Rloginとかなんでも)
* _Virtualbox_ + _Vagrant_ で構築した仮想環境# 必要な知識
* Linux操作に対する知見# 対象リソース
golang 1.18.9-1.amzn2.0.1# 作業内容
* 対象環境へのログイン
* Goのインストール
* Goを使ってみる# 作業開始
## 対象環境へのログイン
1. Vagrantfileのある作業フォルダでGitbashを起動する。
1. ログイン先確認
“`
$ vagrant global-status
“`
1. 仮想マシンの起動
“`
$ vagrant ssh
“`
1. 特権への切り替え
“`
$ sudo su
Go言語での並行処理と並列処理: ゴルーチンとチャネルの活用法
### はじめに
Go言語は、その簡潔さや高いパフォーマンス、そして並行処理や並列処理を容易に実現できる機能によって、多くの開発者から支持されています。この記事では、Go言語での`並行処理`と`並列処理`の実現方法、特にゴルーチンとチャネルを利用した方法について解説します。
### ゴルーチンとは
ゴルーチンは、Go言語独自の並行処理の仕組みで、軽量なスレッドとも呼ばれます。関数の前に`go`キーワードをつけるだけで、新しいゴルーチンを生成できます。ゴルーチンは、メモリ消費が少なく、数十万から数百万のゴルーチンを同時に実行することが可能です。“`go
package mainimport (
“fmt”
“time”
)func printHello() {
fmt.Println(“Hello, Go!”)
}func main() {
go printHello()
time.Sleep(1 * time.Second)
}
“`
[コードを試すにはこちら](https://go-tour-jp.appspot.com/welcome/1)##
[Go言語] スライス初心者ガイド: 空のスライスとnilスライスを理解する
### はじめに
Go言語では、スライスは非常に便利なデータ構造であり、頻繁に使用されます。
しかし、空のスライスとnilスライスの違いや使い分けについて混乱することがあります。
少し気になったので、調べてみたのでここでまとめます。### 空のスライスとnilスライスの定義
まず、空のスライスとnilスライスを定義する方法を見てみる。“`go
files1 := []string{}
files2 := []string
“`files1は、空の文字列スライスで、長さ0、容量0です。
files2は、nilスライスで、同じく長さ0、容量0ですが、内部的にはnilとして扱われます。### 違いについて
**nilチェック**:nilスライスと空のスライスは、nilチェックで区別されます。
nilスライスは初期化されていない状態を示すことが多いため、このチェックを使って初期化処理を行うことができます。“`go
if files == nil {
// filesはnilスライス
} else {
// filesはnilでないスライス(空のスライ
goのポインタがよくわからなかったのでchatGPTに質問してみた
## 疑問
ポインタ型でスライス演算子を使うには括弧がいるらしいです。“`go
*hoge[:i] // error
(*hoge)[:i] // OK
“`## chatGPT理由を聞いてみた。
Q: なぜ「ポインタ型変数に対して直接スライス演算子を適用することはできない」のですか?
![スクリーンショット 2023-03-30 15.49.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851562/ad5256f9-59d4-64b3-9070-1d3b24c6318b.png)つまり、こういうことになるのでしょうか。
“`golang
// 下記はスライス演算子が利用できる
var slice []string{“hoge”, “fuga”} // 配列への参照型
slice2 := make([]int, 3, 3) // 配列への参照型 && 長さ、容量のメタデータ
// 下記はスライス演算子が利用できない
var hoge *[]string //
TourOfGoをやってみた
# GOの基本が知りたくなった
以前、少し書いた(多分interfacesの辺り)が手違いで消してしまった。
やる気が失われたので、基礎をすっ飛ばして
自分が欲しい物を作ってみて学習するスタイルへシフトした。
いや、基本は学んどこう。と反省して復習兼ねて最初からもう一度やる。# TourOfGoやる
## Packages
GOのプログラムはpackageで構成される。
プログラムのエントリポイントはmainパッケージである必要がある。らしいパッケージ名はインポートパスと同じ名前にする必要がある。
package/hoge という場所に作るものはhogeというパッケージにする。## Imports
書き方は2種類– グループ化して書く方法(基本的にこれでよかろう)
“`golang
import (
“fmt”
“math”
)
“`– 1行ずつ書く方法
“`golang
import “fmt”
import “math”
“`## Exported names
goにおいて最初の文字が大文字で始まるものは外部から参照可能なものである。という
ec2を再起動するたびに特定のコマンド実行
ec2起動時にはアプリのバイナリファイルを実行するコマンド
“`
nohup ./main &
“`
をターミナル上で打つ。
ただサーバー代をケチっているため、夜はインスタンスを停止させ、朝にインスタンスを再起動?している。
そのため毎朝ターミナルにssh接続をして上記コマンドを打たないといけない。
今回はそれがとても面倒に感じたためインスタンス再起動時に自動でbashスクリプトを読み込む設定をしてみた。参考にさせていただいたURL
https://qiita.com/Ueken3pei/items/003600c9b1c8435af548上記のページで言うとおりに
ec2インスタンスのユーザーデータの箇所にテキストベースで
MIME-MULTIPART形式でかけばよい。上記のコマンドの場合だと
“`
Content-Type: multipart/mixed; boundary=”//”
MIME-Version: 1.0–//
Content-Type: text/cloud-config; charset=”us-ascii”
MIME-Version: 1.
Go言語における並列処理について
### はじめに
Go言語は、並列処理を容易に実装するための強力な機能であるゴルーチン(`goroutines`)とチャネル(`channels`)を提供しています。ゴルーチンは軽量なスレッドのようなもので、低いオーバーヘッドで大量の並列処理を実行できます。チャネルは、ゴルーチン間でデータの受け渡しを行うための同期メカニズムです。#### ゴルーチンの軽量性
Go言語のゴルーチンは、軽量なスレッドのようなもので、低いオーバーヘッドで大量の並列処理を実行できます。他の言語のスレッドよりもリソース消費が少なく、数千や数万のゴルーチンを同時に実行することが可能です。#### 簡潔な並列処理の構文:
Go言語は、`go`キーワードを使って簡単に並列処理を実装できます。これにより、関数やメソッドをゴルーチンとして実行でき、コードの可読性が向上します。他の言語では、スレッドの作成や管理に多くのコードが必要であることが多いですが、Go言語では簡潔に記述できます。#### チャネルによる同期とデータの受け渡し:
Go言語では、チャネルを使用してゴルーチン間でデータの受け渡しを行い、同期をと
【随時更新中!】Go言語で標準入力から値の受け取り方
# 文字列を一行受け取る。
“`go
package main// データの読み込みに必要なパッケージをインポートしている
import (
“fmt”
“bufio”
“os”
)
func main() {
// データを読み込んでいる
// scは読み込み機能を割り当てる変数
sc := bufio.NewScanner(os.Stdin)sc.Scan()
// 受け取ったデータを変数sayに代入している。
say := sc.Text()
fmt.Println(“Hello ” + say)
}
“`
標準入力
world
実行結果
Hello world# 調べたこと
Go言語の標準ライブラリ(なんかパッケージって呼ばれてる。)
・fmt(パッケージ)
フォーマットされた入出力をサポートする関数を提供します。
例えば、Println関数は文字列をコンソールに表示するために使用されます。
・bufio(パッケージ)
高速な入出力機能を提供しま