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

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

interfaceやprotocolってなんぞ?

## はじめに
私は、現在大学生なのですが、同じ学部の大学生からソフトウェアエンジニアのバイトをできる人が集まりませんでした。そこで今回は使用している`interface`をわかりやすく解説していこうと思います。

Goにおける`interface`は他言語にも実装されており、JavaやObjective-Cも同様の語句で使用・実装できます。ただ、私の専門がswiftなので`interface`と同じ役割の`protocol`を使います。 :pray:
説明上は`interface`を使いますが、コード上では`protocol`と書きます。

## そもそも`interface`とは?

`interface`の説明の前に、、、オブジェクト指向って知ってる?:thinking:

### オブジェクト指向(言語)をざっくり解説
「この世の全てのものは`object(モノ)`であり、`モノ`はそれ固有の処理を有する。その`モノ`が集まってこの世の`モノ`はできている。」みたいな考え方。`モノ`を表現する方法で`class`や`struct`を使用します。
例)荷車:タイヤ(回転して

元記事を表示

同時実行するゴルーチンの数を抑える

ゴルーチンを使って並行処理を書きたいが同時実行数を制御したいという場面は多々ある。メモリ・CPUなどリソースは限られてますから。

## バッファ付きを使ったゴルーチン数の制御
バッファ付きチャネルの次の特性を使って、計数セマフォとして使うことで簡単に実現できる。

– 空きがあれば送信側は待たされない
– 空きがなければ送信側は待たされる(ブロックされる)

“`go
package main

import (
“fmt”
“sync”
“time”
)

const concurrencyNum = 3 // 同時実行数

func main() {
tasks := []string{“タスクA”, “タスクB”, “タスクC”, “タスクD”, “タスクE”}

sem := make(chan struct{}, concurrencyNum)
var wg sync.WaitGroup
for _, t := range tasks {
sem <- struct{}{} // wg.Add(1) go func(t string) {

元記事を表示

【echo】カスタムloggerの実装

# はじめに
ハンドラーの処理をロギングする際に、echo middlewareに用意されているloggerではなくサードパーティのロギングライブラリを利用したかったため、カスタムしたloggerをechoに設定する必要がありました。

以下を前提条件とします。
– Go version:1.19
– echo version:4.0.0
– ロギングライブラリ:logrus

# 実装
logrusをカスタムloggerとして設定する場合は、以下のコードになります。
ポイントは、logrus.Fields構造体のフィールドを増やすだけではなく、RequestLoggerConfigのフィールドにあるLogXxxの値をtrueにしておくことです。
以下のようにフィールドを列挙してログに残したい項目を追加していきましょう。

“`go
log := logrus.New()
e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
LogMethod: true,
LogURI:

元記事を表示

Lima の containerd へ接続してみる

最近、macOS を使い始めて、課題となったのが Linux のコンテナ環境をどうするかという事でした。

あまり余計な事をせずに [containerd](https://github.com/containerd/containerd) が動作するようなものを探したところ Lima を見つけました。

* [Lima](https://github.com/lima-vm/lima)

Lima は Linux 仮想マシンで containerd がビルトインされています。
containerd を操作するための CLI ツール [nerdctl](https://github.com/containerd/nerdctl) (Docker との互換性あり)も導入してくれるので、これだけでコンテナの実行環境が整います。

そこで今回は、Lima の環境を構築するついでに、仮想マシン内の containerd へ Go 言語のコードで接続してみました。

# はじめに

Lima をインストールし、仮想マシンを実行しておきます。

##### インストール例
“`
% brew i

元記事を表示

spreadsheetのURLだけから内容を取得してみた。

今回はシート名が不明な状態でURLだけからシートを取得する方法を書きます。
まずよくあるシートを取得するサンプルコードを紹介します。
読むとわかりますが、spreadsheetのIDとシート名を使って取得しています。

“`go
package main

import (
“context”
“fmt”
“log”

“google.golang.org/api/option”
“google.golang.org/api/sheets/v4”
)

func main() {
spreadsheetID := “1zrqghzR3UJdrS70JLKLgujCnmGFN93vIf1B7XmtblOM”
credential := option.WithCredentialsFile(“test.json”)

srv, err := sheets.NewService(context.TODO(), credential)
if err != nil {
log.Fatal(err)
}
// シート名と参照範囲をくっつけた文字列を使う(シート名だけ

元記事を表示

Goを使ってDynamoDBに一括書き込み

aws-sdk-goを使ってDynamoDBを操作するメモです。
こちらの[リンク](https://docs.aws.amazon.com/ja_jp/code-library/latest/ug/go_2_dynamodb_code_examples.html)を見ながら基本的なCRUDは一通りできたのですが、一括処理はうまくできませんでした。
一括書き込みの箇所についてデモを作成しようと思います。

### 環境
`go version 1.17.2`

`aws-sdk-go v1.44.180`

### 前提
DynamoDBにユーザ情報を一括登録する想定です。
ユーザ情報はHTTPリクエストボディから受け取ります。
Lambda上で受け取ったデータを構造体に変換し、DynamoDBに書き込みます。

### 構造体を定義
ユーザ情報を表現する構造体を定義します。

“`go:main.go
type User struct {
ID string `json:”id”`
Name string `json:”name”`
}
“`

### リクエストボディか

元記事を表示

Go言語のクリーンアーキテクチャ例

**やりたいこと**
ハンドラー⇒ユースケース⇒リポジトリのようなプロセスをクリーンアーキテクチャな作りにしてテストをしやすくする。

**サンプル**
あくまで例となりますので1ファイルに纏めております。

“`golang
// main.go
package main

import “fmt”

// handlerパッケージに置くイメージ
type Handler struct {
uc UsecaseIF
}

type HandlerIF interface {
HandlerProcess()
}

func NewHandler(
uc UsecaseIF,
) HandlerIF {
return &Handler{uc: uc}
}

func (h *Handler) HandlerProcess() {
fmt.Println(“Handler Process”)
h.uc.UsecaseProcess()
}

// Usecaseパッケージに置くイメージ
type Usecase struct {
db DBIF
}

type Useca

元記事を表示

Go言語のオーバーライド例

**やりたいこと**
親structを取り込み子struct側のメソッドでオーバーライドさせる。

**親のみ**

“`golang
// maing.go
package main

import (
“fmt”
)

type Parent struct {
NameParent string
}

func main() {
c := Parent{“親”}
c.Method()
}

func (p *Parent) Method() {
fmt.Println(p.NameParent)
}
“`

**結果**

**親を取り込みオーバーライド**
Parentをembeddedフィールドとして取り込み、Methodレシーバで値を操作する。

“`golang
// main.go
package main

import (
“fmt”
)

type Parent struct {
NameParent string
}

type Child struct {
Parent // embedded
NameChild string
}

元記事を表示

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

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

つまり、スイッチを下げるがごとく、**ビットマスクが `1` なら、どのような状態であっても `0` にしたい**のです。いわゆるひとつの、**論理演算における「非含意ひがんい」(`P ⊅ Q`)をしたい**のです(ゆうて、そんな名前が付いてるって知らんかったけど)。

## TL; DR (今北産業)

1. やりたいことは以下。
![スクリーンショット 2023-01-18 9.58.14.pn

元記事を表示

Go言語のテストファースト例

**やりたいこと**
外部APIやDBへのアクセス処理が含まれるメソッドをモックしてテストする。

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

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

“`golang
// main.go 1つ目のファイル
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実行結果**
本物のG

元記事を表示

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

元記事を表示

OTHERカテゴリの最新記事