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

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

【Golang】ビット演算で特定ビットを 0 にする【ビットの非含意(`P ⊅ Q`)反転ではない】

> Go 言語(以下 Golang)で、バイトデータの「特定箇所のビット」を確実に `0` にしたい。
> 0b100001000b10000000
> 0b100000000b10000000
>

`0b100` のマスクを XOR 演算(`^`、排他的論理和)して反転させるも、反転なので 2 回適用すると `1` に戻ってしまいます。

0b10000000 ^ 0b100 = 0b10000100 (`P XOR Q`)
0b10000100 ^ 0b

Go言語の簡単なテスト方法

**用途**
外部APIやDBへのアクセス処理が含まれるメソッドをモックしてテストする場合など。

以下★のメソッドをテストします。

**実装側**
外部アクセス処理のあるGetメソッドを外から差し込んで利用します。

```golang
package main

import (
"fmt"
"net/http"
)

type A struct {
Name string
}
type AIf interface {
Get() string
}

func main() {
a := A{"本物"}
s := Example(&a)
fmt.Println(s)
}

// ★テスト対象メソッド
func Example(a AIf) string {
s := a.Get()
return s
}

func (a *A) Get() string {
_, _ = http.Get("yahoo.co.jp")
return a.Name + "のGetメソッド"
}
```
**main実行結果**
本物のGetNameメソッド

**実装側**

go mod tidyでgitlabのリポジトリimportが失敗する

# はじめに
本記事はあくまで個人のタスクにおける備忘録としての投稿であり、細かい設定条件や開発環境の記載は省略しています。

# 事象
`go mod tidy`で依存関係を整理しようとした際に
```terminal
fatal: could not read Username for 'https://gitlab.***/***/***.git': terminal prompts disabled
Confirm the import path was entered correctly.
```
というエラーが出て失敗する。

# 調査
1. エラー内容をそのままググる
するとこういう記事がヒットする
https://jnst.hateblo.jp/entry/2016/10/17/210612

要はgitのレポジトリへのアクセスをする際に権限がないため怒られているとのこと。

2. 現状の`.gitconfig`を見てみる。
```
[credential]
helper = !aws codecommit credential-hel

Goでbuild constraintsを使ってビルドを分ける

Goではbuild constraints(build tagsとも呼ばれる)を利用することで、異なるビルドを作り分けることができます。
この機能を利用することで、デバッグ用とリリース用や無償版と有償版といった複数のバリエーションのビルドを作ることができます。

## 本記事でのGoのバージョンについて

本記事ではGo 1.17以降を対象とします。

build constraintsの書き方はGo 1.17から変更になったのですが、1.16は既にサポートされていないバージョンなので、本記事でも扱わないこととします。

詳細については https://go.dev/design/draft-gobuild を見るようにとリリースノートにもあるので、以前の記法と「なぜ変更になったのか」が気になる方はそちらを御覧ください。

## build constraintsの付け方

build constraintsは以下のようにファイルの先頭に`//go:build 条件`という形式のコメントを書きます。

条件の部分は単純にタグ名を指定する以外にも、if文のような`(A || !B)`のよ

CircleCIでGo1.19とgcoudコマンドを使用できる環境を作成する方法

## 概要
GoのAPIテストをCircleCIと連携する際に詰まったので備忘録として投稿します。

### 要件
今回の用件として、GCPのサービスアカウントを使用すること、Goのバージョンを1.17以上にすることがあります。
また、GCPのサービスアカウントを使用する際に`gcloud`コマンドを使用するので、Go1.17以上 + gcoudコマンドを使用できる環境が必要です。(厳密には[こちらのコマンド](https://cloud.google.com/sdk/docs/authorizing?hl=ja#authorize_with_a_service_account)を使用したいと思っています)
筆者が調べた限りでは、Go1.17以上で`gcloud`コマンドを使用できるDocker imageは見つからなかったので自作で環境を構築する必要がありそうでした。

###### GCPのサービスアカウントを使用する理由
テスト実行時にGCPと連携する必要があるためです。
###### GOのバージョンが1.17以上である理由
実装の都合上なのでCircleCIとの連携に深く関係

Protocol Buffersの基本的な内容に関してまとめてみた

# 初めに
業務でgrpcを使用する機会があったので、プロトコルバッファを[こちら](https://developers.google.com/protocol-buffers/docs/overview)のサイトを見ながら学習しました。
その内容をアウトプットのため投稿します。
また、使用する言語はGoでproto3を使用します。

# 概要
プロトコルバッファは、構造化されている型付けされたデータを言語やプラットフォームに依存せずシリアライズすることができます。
> 定義言語(インタフェース定義言語)・シリアライズ形式・各言語向けランタイムライブラリ・プロトコンパイラ生成コードの4要素からなる[2]。
出典:[Wikipedia](https://ja.wikipedia.org/wiki/Protocol_Buffers)

## 簡単な流れ
プロトコルバッファを使用する際の簡単な流れは以下です。
1. `.proto`ファイルにデータの定義を行う。
2. 指定した開発言語のオブジェクトを生成する。
3. バイナリファイルに変換されてデータを送受信する。

## 特徴
プロト

main.goを実行するたびにうるさいAvastを無効にする

Goのチュートリアルを始めました。

ファイルを変更して、
```go
> go run main.go
```
で実行するたび、「ポンポンポン」と警告音を出すAvastさん。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599506/85d847fa-7d06-e3e9-fbf8-553e4b81854b.png)

一時ファイルの実行に対して脅威検出をしてくれていますが、毎回出てくると煩わしいので無効化します。

Go実行時の一時ファイルに対するAvastの脅威検出を無効にする方法のメモです。
※ 一切責任を負えません。自己責任で設定してください。

# 環境

- Avast Version:22.12.6044 (ビルド 22.12.7758.769)
- Windows 10 Home 22H2
- GOCACHE=C:\Users\[user]\AppData\Local\go-build
- GOROOT=C:\Program Files\Go

# 無効可手順

- A

Goで値渡しとポイント渡しのベンチマーク比較

# 条件
インライン化しないように指定(go:noinline)

下記の条件の組み合わせベンチマークテスト実行
+ ワード(1word=64bit)数 1~10
+ 関数 or 値レシーバ or ポインタレシーバ
+ 引数1~3、戻り値0~2

# 結果

https://github.com/shunsukuda/go-val_vs_ptr/blob/main/bench_result.txt

https://github.com/shunsukuda/go-val_vs_ptr/blob/main/bench_global_result.txt

+ ポインタのみの場合は常に一定
+ 引数と戻り値の数が少ない内は5~6ワード目まで差は小さい
+ 引数と戻り値の数が多くなると2ワード目からでも2倍程度の差になる
+ 2ワード以上の場合は素直にポインタを使用するほうが無難
+ ヒープ割り当て発生時は要計測

PHPerが学ぶGo言語② 関数・構造体

豚さんです。
今回は関数・構造体について書いていきます。

Go言語にはクラスが存在しないという事前知識はあり、
代わりに構造体というものが存在するということは
調べて何となく知っている所からスタートです。

まずは、関数の説明を書いていき構造体の説明に移っていきます。

※ 注意:内容はPHPか何かの言語を書いたことがある方向けなので、
説明を割愛している箇所は多々ありますので、ご了承ください。

**go version go1.19.4 darwin/amd64**

# 1. 関数
前回の記事では、とりあえずmain関数で実行していましたが
どういうことか理解していませんでした。
Go言語はmainパッケージのmain関数で実行されるんですね。
```sample.go
// Goのプログラムはmainパッケージから実行する
package main

import "fmt"

func main() {
fmt.Println("テスト")
}
```
```
$ go run sample.go
テスト
```

では、

Goのファイルシステム(io/fs)を実装してみる

## はじめに

Goの`io/fs`パッケージはファイルシステムを抽象化してプログラム内で扱えるようにするためのインターフェイスを提供するもので、Go 1.16から利用可能になりました。

今回はこのパッケージの理解のために、あらかじめ用意した固定内容を返却する仮想的なファイルシステムを実装してみます。

## ゴール

下記の内容を読み取ることができるように`fs.FS`を実装します。

| ファイルパス | 内容 |
|:-|:-|
| `foo` | (ディレクトリ) |
| `foo/bar` | `hello` |
| `foo/baz` | `world` |
| `foo/qux` | (ディレクトリ) |
| `foo/qux/quux` | `hello world` |

また、実装したファイルシステムが期待通りに動作していることを確認するために`http.FileServer`を利用してブラウザ上でファイルの内容を確認できるようにします。

## 実装すべきインターフェイス

下記はGoのファイルシステムを実装する上で必須となるものです。

* [`fs.FS

Dapr Actor Componentの逐次実行はどこで保証されている?

# TL; DR

Actor実行時に一意なキーを発行しロックすることで、同じIDのアクターが同時に2つ以上起動しないようにしている

https://github.com/dapr/dapr/blob/e6ba9d0f3d2e71959342392d6ab9d835a0758fd2/pkg/actors/actors.go#L434

# はじめに

DaprのActor Componentは、ターンベースのアクセスモデルを採用しています。各アクターはメッセージを逐次的に処理するため、あるタイプ、IDのアクターは常に1つの呼び出ししか処理しません。
言い換えると、**アクターのメソッドで状態更新の競合を考慮する必要が無くなります**。

https://learn.microsoft.com/ja-jp/dotnet/architecture/dapr-for-net-developers/actors#turn-based-access-model

```csharp:上記ページより引用
public async Task IncrementAsync()
{

【Golang】バイトデータ内のビット 1 の数を数える【ハミング距離】

> [バイト](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88_(%E6%83%85%E5%A0%B1))・データの[ハミング距離](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%9F%E3%83%B3%E3%82%B0%E8%B7%9D%E9%9B%A2)を算出するため、**データのビットが 1 の数を数えたい**。
>
> ```go
> int(123) = (0b10000000) ---> 1 個 // ハミング距離 = 1
> int(240) = (0b11110000) ---> 4 個 // ハミング距離 = 4
> int(255) = (0b11111111) ---> 8 個 // ハミング距離 = 8
> ```

## TL; DR (今北産業)

1. [math/bits](https://pkg.go.dev/math/bits#OnesCount) パッケージの [OnesCount](http

Go でホストのプライマリ IP アドレスを取得する (Linux)

[`github.com/google/gopacket/routing`](https://pkg.go.dev/github.com/google/gopacket@v1.1.19/routing) パッケージを使う.
インターネット上のホストへの経路とソース IP アドレスを取得することができる.

:::note warn
Linux しか対応していない模様
:::

```main.go
package main

import (
"fmt"
"net"

"github.com/google/gopacket/routing"
)

func main() {
router, _ := routing.New()
internetHost := net.IP{8, 8, 8, 8}
_, _, primaryIp, _ := router.Route(internetHost)

fmt.Printf("ip = %v\n", primaryIp)
}
```

## `out of order iface...` のエラーが出る時

Docker など

スライスからスライスを作成して、appendしたときの挙動が想像と違った

あるスライスからインデックス指定で新しいスライスを作ってから、appendで要素を追加した場合、
新しいスライスにしか影響を与えないと思っていたのだが、必ずしもそうではないらしい。
以下はversion 1.19.2で検証した結果である。

```golang
package main

import "fmt"

func main() {
nums1 := []int{1, 2, 3, 4, 5}
s1 := nums1[:4]
fmt.Printf("len = %d, cap = %d\n", len(s1), cap(s1))

s1 = append(s1, 6) // (1)
s1[0] = 10 // (2)
s1 = append(s1, 7) // (3)
s1[1] = 20 // (4)

fmt.Printf("nums1 = %v\n", nums1)
fmt.Printf("s1 = %v\n", s1)
}
```

```bash
# 出力結果
len = 4, cap = 5
nums1 = [

mackerel-agent-plugin に Pull Request してみたかった

# TL;DR

自分の調査能力が甘すぎて完全に無駄な開発と記事作成をしてしまったので供養のために。読む価値はあまりありません。
Mackerel の plugin は [公式リポジトリ](https://github.com/mackerelio/mackerel-agent-plugins) だけじゃなく [plugin registry](https://github.com/mackerelio/plugin-registry) も探しましょう。
あと、今は公式リポジトリではなく plugin registry に PR を出すものらしいです。
ちゃんと公式のドキュメントを読んで、既存のプラグインを探してから開発しましょう。

# 背景

Go で Slack に常駐する bot をいくつか書いたり、mackerel にカスタムメトリックを投稿するスクリプトを書いたりということができるようになってきたあたりで、passenger のリソース使用量を監視する必要が生じた。
普段は自社サービス・サーバへゴリゴリにロックインした雑なカスタムメトリックばかり作っていたので特に OSS

GraphQLのschema.graphqlsファイルをバックエンドとフロントエンドで同期するベタープラクティス

# この記事は何か?
フロントエンドとバックエンドをGraphQL APIで連携する場合、スキーマファイル(schema.graphqls)をどうやって連携するか悩んでいました。
色々と試行錯誤して、ベストプラクティスとまでは言えないまでもベタープラクティスに近い解決策に至ったので共有してみます。

# 構成
バックエンドは Go, Gin, gplgen、
フロントエンドは TypeScript, React, Next.js

のSPA構成でそれぞれ別リポジトリで管理しています。

# やりたいこと
バックエンドとフロントエンドでschema.graphqlsファイルから型を自動生成したい。
※ schema.graphqlsファイルの管理はバックエンドが主導で行う前提です。

# やりたくないこと
graphqlsファイルの二重管理。バックエンドの差分を逐一フロントエンドでコピーして追従、というケースだけは避けたい。

# 辿り着いたベタープラクティス
バックエンドでは、[gplgen](https://gqlgen.com/)のコマンドによりGoの型を自動生成し、
フロントエン

Go:健康データの簡易APIサーバーの作り始め

作成:2023年1月11日

体重など健康データを保存するアプリとバックエンドを作ってみたく、Go でバックエンドを作成する為の情報収集と練習の為に、バックエンドをシンプルなGo言語で書いてみます。

# 事前準備

Postmanをインストールしておきます([参考リンク](https://qiita.com/nlog2n2/items/b5e11332087c335e126e))

# 簡易APIサーバー

GETするコードです(githubのコード置き場:[qiita20210111](https://github.com/ryoyuki6/go-api202301/blob/qiita20230111/main.go))
```go:main.go
package main

import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)

type HealthData struct {
UserID int `json:"user_id"`
Weifgt float64

Goの並行処理に関して簡単にまとめてみた

## 初めに
[A Tour of Go](https://go-tour-jp.appspot.com/concurrency/1Go)の「Concurrency」項目を終了したので、簡単にGoの並行処理に関してまとめました。
今回は簡単な挙動をまとめたものになるので、詳細に理解したい場合は[Go言語による並行処理](https://www.oreilly.co.jp/books/9784873118468/)等の書籍を読むのも良いと思いました。

## 基本的な挙動
Goはgoroutineという軽量のスレッドを作成して並行処理を行います。
goroutineは下記のコードで作成できます。
```go
go 関数呼び出し
```

Goは通常の処理にもgoroutineを使用します。
下記だと、最初にmainのgoroutineが作成され、`go say("new goroutine")`のコードで新しいgoroutineが作成されます。
そのため、下記ではmainのgoroutineと新しいgoroutineの2つが動作していることになります。

```go
func say(s

PHPerが学ぶGo言語① 変数・定数・配列

どうも、豚さんです。
今回はGo言語に関して書いていきます。

今回もPythonみたいに深く触れずに記事を書いていきたいと思います。
Pythonの記事同様、変数から配列の記事で始めていきます。

公式サイトのサンプルソースを変えて使っています。

プログラムは *func main() {}* の中を見てください。
**あくまで変数〜配列についてです。**
それ以外はまだ理解していないので、ご了承ください。

※ 注意:内容はPHPか何かの言語を書いたことがある方向けなので、
説明を割愛している箇所は多々ありますので、ご了承ください。

**go version go1.19.4 darwin/amd64**

# 1. 変数
変数宣言時は「var 変数名 型名」で宣言します。
値を代入しない時の初期値はint型だと0、とstring型だと""です。
```sample.go
package main

import "fmt"

func main() {
// 型が明確な場合は、型の記載が不要
var num int
va

【ド基礎】Goコマンドをフローで整理する

GoのDocker環境を立てている時に `go install` と `go mod tidy`の厳密な動作内容などでつまづいたのでフローで整理しておきます。正しいんだろうかと悩んでいるのでお気軽にツッコミください。

![スクリーンショット 2023-01-09 10.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893208/f81fa14f-ef74-0a91-77d3-fc593923063f.png)

# `go install`

外部のモジュールを新しく導入したい時に使う。ただソースコードをダウンロードしてくるだけではなく、ダウンロードしたモジュールを実行可能なバイナリにビルドもしてくれるコマンド。

ってことは差分が `go install` しただけであれば理論上は `go build` しなくて良い?

# `go mod tidy`

go.modファイルとソースコードとの整合を取ってくれるコマンド。go.modとgo.sumに必要なエントリを加え不要なエントリを削除