Go関連のことを調べてみた2023年04月07日

Go関連のことを調べてみた2023年04月07日

Goプログラム開発におけるモジュール管理

Goプログラムでのパッケージ探索方法やモジュール管理についてざっくりと調べてみたので解説する。

## GOPATHモードとモジュールモード

Goには、GOPATHモードとモジュールモードが存在しており、`go.mod`が存在するか否かでGoが自動的に判断する。

– `go.mod`が有る:モジュールモード
– `go.mod`が無い:GOPATHモード

モジュールモードは、Go 1.16以降で利用可能になったモードで、GOPATH変数を使用しないように設計されている。
GOPATH変数の代わりにGoモジュールという仕組みを使用して依存関係を管理している。
GOPATHモードでは、GoパッケージはGOPATHディレクトリ以下に配置され、importパスの一部として指定していたが、モジュールモードではモジュールごとにgo.mod(モジュールファイル)が配置されることで管理している。

## パッケージの探索手順

**モジュールモード**における、パッケージの探索は以下の手順で実行される。

1. カレントディレクトリのvendorディレクト

元記事を表示

GoのDocker開発環境を作る

Goで開発環境を作る時Dockerを使っているのですが、いつもDockerfileやdocker-composeの内容を忘れてしまうので、メモしておく。

Dockerfile
“`
#go version
FROM 1.20-alpine3.17

#update & install (vimやbashを入れとくと便利)
RUN apk add –update && apk add git && apk add vim && apk add bash

# 作業ディレクトリ作成
RUN mkdir /go/src/app

# 作業ディレクトリ設定
WOKRDIR /go/src/app

# ホットリロード用にairをインストール
RUN go install github.com/cosmtrek/air@latest

# airを実行
CMD [“air”]
“`

docker-compose
“`
version: ‘3.9’
services:
backend:
build:
context: .
dockerfile: D

元記事を表示

HomebrewでインストールしたGoをアンインストールする方法(Mac)

以下のようにして削除する

“`
$ brew list
==> Formulae
autoconf m4
azure-functions-core-tools@4 mysql
brotli node
c-ares openssl@1.1
ca-certificates openssl@3
go pkg-config
icu4c protobuf
libcbor rbenv
libevent readline
libfido2 ruby-build
libnghttp2 xz
libuv zlib
lz4 zstd

==> Casks
powershell
$ brew uninstall go
Uninstalling /usr/local/Cellar/go/1.20.2… (11,975 files, 234.1MB)
$ brew list
==> Formulae
autoconf mysql
azure-functions-core-tools@4 node
brotli openssl@1.1

元記事を表示

Goのhtml/templateやGinでコメント文を削除させずに出力させたい時

# はじめに
よくあるWebサイトのhtmlを覗くとコメント文が書いてあることがよくあります。
ですが、Goで書いたWebサーバーはテンプレートを通すとコメント文がすべからく削除されます。

ブラウザ上では基本的に見ることは無いので高速化するのに助かる機能ですが….

他のWebサーバーで存在するのにGoには無いのが気持ち悪いのでコメントアウトを記述できるようにします(~~隠しAA書けないし~~

↓テンプレートに使うファイル
“`templates/index.html




(適当な内容)
{{““ | safeHTML}}



“`

# html/templateのみの場合
“`main.go
package main

import(
“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 main

import “fmt”

func main() {
name := “Alice”
age := 30
fmt.Print(“Name:”, name, ” Age:”, age) // 出力: Name:Alice Age:30
}
“`

## fmt.Printf
`fmt.Printf`関数は、書式付きの文字列と一緒に与えられた引数を標準出力に出力します。最後に改行は追加されません。

“`go
package main

import “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 main

import “fmt”

func main() {

weather := “晴れ”
fmt.Printf(“今日の天気は%sです”, weather) // 出力結果:今日の天気は晴れです
}
“`

整数の場合は`%d`を使う
“`go
package main

import “fmt”

func main() {
month := 6
day := 19

fmt.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 main

import (
“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において最初の文字が大文字で始まるものは外部から参照可能なものである。という

元記事を表示

OTHERカテゴリの最新記事