Go関連のことを調べてみた2022年08月28日

Go関連のことを調べてみた2022年08月28日

Windows(WSL2)上にdoodのコンテナを作る

# 最初に結論
これをクローンしてコンテナの中に入ればおk

https://github.com/Mkamono/golang-dood-host-sample

# DooDとは
Docker outsite of Dockerの略です。Docker内部のコンテナからホストのDockerを操作する方法です。DinD(Docker in Docker)という方針もありますが今回はこちらで。
# どうしてそんなことを?
インターンで働いている企業の開発環境がMacです。Docker関連にMakeファイルが用意されており、Dockerコマンド、Goコマンド、Unix系コマンドが必要になったためです。
できるだけローカルの環境を汚さずに開発をしたかったため、Docker上に環境を置きたいと思ったのですが、環境構築の時点でGoのコマンドを使用しているため本来であればローカルにGoをインストールする必要がありました。
DooDを採用することで、ローカルのように扱えるGoのコンテナ、実際に運用しているコンテナの2つによって、擬似的に同じ環境を作ります。

# ディレクトリ構成
“`txt:ディ

元記事を表示

GoでヘッドレスChromeを動かして、ブラウザのLocalStorage取得するメモ

## やりたいこと
とあるサービスをブラウザで開いたときに、ブラウザのlocalStorageに保存されている情報を取り出したい

今回は例としてQiita

## バージョン/パッケージ
* go : 1.17
* chromedp: v0.8.3

## 該当のページをヘッドレスChromeで開くまでのコード

まずは該当のページを開くまで
以下のコードではQiitaのトップ画面のURLをurl変数に入れています。

“`go
package main

import (
“context”
“fmt”
“github.com/chromedp/cdproto/emulation”
“log”
“time”

“github.com/chromedp/chromedp”
)

var userAgent string = “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36”

// 開

元記事を表示

Goの fs.FS をOSのファイルシステムにマウントしたい

# fs.FSのファイルを他のプロセスに渡したい

Go 1.16 で追加された `io/fs` パッケージで色々なファイルシステムに共通のインターフェイスでアクセスできて便利になりました.この`fs.FS`の中身にシェルやエクスプローラからアクセスして操作できると便利そうです.

例えば,ネットワークストレージのクライアントを Go で実装する場合 `fs.FS` インターフェイスを実装すると思いますが,そのクライアントをそのままマウントできれば他のアプリケーションからデータにアクセスできます.

# GoでFUSEを使う

大抵の環境では,ユーザプログラムがファイルシステムを提供するためのFUSEという仕組みが使えます.

Linuxの場合は,[go-fuse](https://github.com/hanwen/go-fuse) というbindingsがあります.

https://github.com/hanwen/go-fuse

専用のインターフェイスを提供する必要があってfs.FSを使うのは少し面倒ですが,高機能かつ活発に開発が続いています.

Windowsの場合は,[

元記事を表示

Go言語~deferについて~

こんちには!
LIFULLエンジニアの吉永です。

本日はGoのdeferについて、コードレビューしていて「あれ?これどう動くんだろう?」ってちょっと判断に迷ったdeferの記述方法があり、改めてdeferについてと、Go Playgroundで動作確認した結果をまとめました。
※[Go 強化月間](https://qiita.com/official-events/ae80b010f51f7018891a)を開催中らしいです!

## deferとは?

### deferの公式ドキュメント

https://go.dev/ref/spec#Defer_statements

### 特徴
遅延実行の為の仕組みで、JavaやC#など多数のプログラミング言語で採用されているtry~catch~finallyのfinallyと似たようなものですが、単純比較すると下記のような特徴を持ちます。

– return時だけでなく、panic時にも実行される。
– 一つのブロック内に複数のdefer定義が可能。
– deferで定義された処理はLIFO(Last In First Out)で実行さ

元記事を表示

【#55 エンジニア転職学習】Goでスクレイピングプロジェクト(完成)

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

間隔が空いてしまいましたが、
スクレイピングのプロジェクトが一旦完成しました。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。

https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容

* **Goで求人情報のスクレイピング ←Topics!!**

# Goで求人情報のスクレイピング
前回から取得したURL一覧の各求人情報を取得してくる機能、
その情報をMySQLからCSVファイルにエクスポートする機能を追加しました。

各ファイルのおおまかな役割は以下になります。
“`
job_offer_scraping/
├── main.go –> DBコネクタ起動、スクレイピング、CSV出力実行
├── csv
│ └── csv.go –> MySQLのmynavi_jobsテーブルから

元記事を表示

Goでerrors.New()の値を比較するテストでイコールにならない

# はじめに

Goを始めたばかりでAPIを一つ作成してテストに挑戦したところかなり沼ってしまいました
原因を解明するのにかなり時間がかかってしまったので初心者のためにまとめます
自分が探していた情報がある記事がなかったので(仕組みを知っているならあたりまえの理由だった)、役に立てばと思います

# 問題

“`go:main.go
package main

import (
“errors”
“fmt”
)

func main() {
err1 := errors.New(“error”)
err2 := errors.New(“error”)

fmt.Println(err1 == err2)
}
“`

この結果が`false`になってしまうのが理解できずにテストでも同じような比較をしていたのでテストが通らず困りました

# 解決方法

これは`errors.New`の処理をみれば納得できます

“`go
func New(text string) error {
return &errorString{text}
}

// errorString is

元記事を表示

Golang reflectパッケージのお勉強

## TL;DR
reflectパッケージを使うと、構造体のタグの値を取得できる。(実行時に構造体の値から)

## はいり
今回は[Reflectパッケージ](https://pkg.go.dev/reflect)について勉強します

パッケージを勉強するときはexamplesを一通り見て回ります。

その際exampleのコードを見ながら自分でもちょっとしたコードを書くので、そのコードを載せます。

Reflectパッケージには8つのexampleがありました。
順番に見ていきましょう

Kind
MakeFunc
StructOf
StructTag
StructTag.Lookup
TypeOf
Value.FieldByIndex
Value.FieldByName

## Kind

まずは定義を見ましょう。型の名前っぽいものが羅列されてます。

“`go
type Kind uint

const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uin

元記事を表示

Goのテストでiniファイルの読み込みでエラーがでる(no such file or directory)

# はじめに

仕事でGoのテストを書き始めたのですが、ファイルの読み込みでつまずいたので共有します

# 問題

以下のコードでGoのテストの実行中に途中でエラーが発生してしまいました

“`go:base_test.go
func LoadConfig() {
cfg, err := ini.Load(“config/config.ini”) # ここでエラー
if err != nil {
log.Fatalln(err)
}
“`

“`
b7159993c977:/go/src/test# go test
2022/08/26 02:35:22 open /config/config.ini: no such file or directory
“`

main.goで呼び出すときは動いていましたなぜかテストで動かすと動かなくなりました

# 解決方法

ファイルパスを絶対パスで指定したところテストが動きました

“`go:base_test.go
func LoadConfig() {
cfg, err := ini.Load(“/go/src/con

元記事を表示

【Golang】Go言語のappendにおける … (ドット3つ)の意味

## はじめに
append関数を使用する際に「…」が出てきたので、その使い方をまとめます。
※バージョン:1.18.4

## append関数
Go言語では、スライスの最後に値を追加するときに append 関数を使用します。
`func append(slice []Type, elems … Type) []Type`([公式ドキュメント](https://pkg.go.dev/builtin#append)より)

要素ではなく、スライスを追加したい場合、次のようにスライス変数の後ろに「…」を書きます。
`slice = append(slice, anotherSlice…)`
スライス変数の後ろに「…」をつけることで可変引数の関数にスライスを展開して渡すことができます。

実際にサンプルを用いて確認します。
#### サンプル
“`main.go
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{10, 20, 30}

slice1 = append(slice1, slice2..

元記事を表示

goで文字列比較の速度を検証

# はじめに
goで文字列比較をする際にどの方法が早いのか気になったので検証してみました。

比較条件は以下とします

– 文字列の長さを固定
– 完全に一致する2つの文字列を比較
– 10,000,000回(1千万回)繰り返した時の実行時間の平均を測定(go test benchコマンド)
– 正規表現は含まない

## 比較結果

**結果:どれを使ってもあまり変わらないことが分かりました**
※ 完全に一致する文字列で検証した場合

凡例は以下の比較方法を表しています。
具体的な実装は各リンク先をご参照ください。

– ① `Equal` : [文字列A == 文字列B](#文字列a–文字列b)
– ② `Byte` : [bytes.Compare(文字列A, 文字列B)](#bytescompare文字列a-文字列b)
– ③ `HasPrefix` : [strings.HasPrefix(文字列A, 文字列B)](#stringshasprefix文字列a-文字列b)
– ④ `HasSuffix` : [strings.HasSuffix(文字列A, 文字列B)](#

元記事を表示

Cobraのコマンドをテストする

## 概要
CobraはGoでCLIを作成するのにすごく便利です

https://cobra.dev/

Cobraで作成したコマンドをテストするにはコツが必要で、以下の記事がとても参考になる

https://zenn.dev/spiegel/articles/20201018-cli-with-cobra-and-golang

ただ、雛形の修正など手間もあるので、より簡易的にテストする方法をまとめる

## コマンドの作成
`sub`というサブコマンドを持ったCLIを作成します
“`sh
$ go mod init
$ cobra-cli init
$ cobra-cli add sub

$ go run main.go sub
sub called
“`
“`go:cmd/sub.go

var subCmd = &cobra.Command{
Use: “sub”,
Short: “A brief description of your command”,
Long: `A longer description that spans multiple

元記事を表示

Go 言語スプレッドシートライブラリ:Excelize 2.6.1 がリリースされました

![Go 言語スプレッドシートライブラリ:Excelize 2.6.1 がリリースされました](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144042/7e5c285e-244b-e46c-ac83-64686b6f242a.png)

Excelize は、純粋な Go で記述されたライブラリで、XLAM / XLSM / XLSX / XLTM / XLTX ファイルの読み書きを可能にする一連の関数を提供します。Microsoft Excel™ 2007 以降で生成されたスプレッドシートドキュメントの読み取りと書き込みをサポートします。 高い互換性により複雑なコンポーネントをサポートし、大量のデータを含むワークシートからデータを生成または読み取るためのストリーミング API を提供します。

場合によっては、既存の Excel ドキュメントコンテンツの読み込み、新しい Excel ドキュメントの作成、既存のドキュメント(テンプレート)に基づく新しい Excel ドキュメントの生成、Excel

元記事を表示

FastHttpd で nginx を代替してみる

[valyala/fasthttp](https://github.com/valyala/fasthttp) を使って [fasthttpd](https://github.com/fasthttpd/fasthttpd) という http サーバを作ってみました。

大きなサービスでは ALB や Google Load Balancer 使うのですが、小さなサービスではまだまだ http サーバ使ってます。近頃の情勢でなんとなく nginx に代わるサービスないかなーと探していたところ valyala/fasthttp に出会い、開発に着手しました。

早速ですが、以下は私がよく使う nginx の設定ファイルです。 バックエンドは node や php で静的ファイルは nginx で配信します。

“`
upstream backend {
server 127.0.0.1:8000;
}

server {
listen 80 default_server;
return 302 https://$host$request_uri;
}

serv

元記事を表示

コメント化の切り替えTips

# 概要

リファクタリング等を行う際に元の処理と新しく作った処理を切り替えるのに「ここからここまでをコメントアウトして…ここからここまでを有効化にして…」というちょっと面倒な作業を解決するTipsです

# 解決策

“`php
/*/
processA(); // ここがコメントアウト状態
/*/
processB();
//*/
“`

“`php
//*/
processA();
/*/
processB(); // ここがコメントアウト状態
//*/
“`

(Qiita上でシンタックスハイライトが効いてくれているのでわかりやすい・・・w)

CやPHPやGo、JavaScriptその他諸々の言語で採用されている↓の場合に使用できます。

“`php
// 1行コメントアウト

/*
複数行コメントアウト
*/
“`

:::note warn
ただしPHPDocのような書き方のコメントが途中にあるとうまく動いてくれないので注意

“`php
//*
var_dump(‘a’);
/*/

/**
* PHPDOcとか
*/
var_dump(‘b

元記事を表示

Goから外部コマンドの呼び出しではPATHの「~」が展開されない

## Goから外部コマンドの呼び出しではPATHの「~」が展開されない

Goで書かれたプログラムから外部コマンドを呼び出す場合、環境変数PATHに~(チルダ:ホームディレクトリ)は展開されないので、~/bin/のようにPATHを通している場合、実行に失敗します。原因がわからず結構はまりました。

以下のように~を使わず、$HOMEを展開し回避します。

“`
export PATH=”$HOME/bin:$PATH”
“`

たまにはまっている人がいる問題のようなので([例](https://github.com/kubernetes-sigs/aws-iam-authenticator/issues/136))、記事として日本語で共有しておきます。

## やりたかったのは

WSL2の環境で、chezmoiから1Password CLIを利用しているのですが、Linux版のCLIはWSL2のホストで動いている1Password GUIと通信してくれません。そのため、1Passwordの長いマスターパスワードを打ち込む必要があります。
一方、Windows版の1Password

元記事を表示

Go における HTTP リクエストの受け取り方

## 前回

https://qiita.com/BitterBamboo/items/6119f7986a04c5a0ac57

## HTTPリクエストの構造

`net/http` におけるハンドラ(関数)は、以下のように `*http.Request` という引数を持っているのでした。

“`go:とあるハンドラ(関数)
func hoge(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, “hoge”)
}
“`

このハンドラ(関数)の引数にある `http.Request` の構造は下記のようになっています。

“`go:net/http
type Request struct {
// 省略
Header Header
// 省略
Body io.ReadCloser
// 省略
Form url.Values
PostForm url.Values
MultipartForm *multipart.Form
// 省略
}
“`

`net/http` を用いた Web アプリで

元記事を表示

GoのswaggerでAPIを登録しているのにAPI一覧が表示されない

# はじめに

GoでSwaggerを利用したのですが、APIを設定しているのに表示されなくなったのでまとめていきます
始めて利用する際に起きそうな現象でしたので参考になればと思います

# 問題

APIを1つ登録していたのですが、そのAPIが突如表示されなくなりました
とくにエラーがでているわけでもない、変なコードを加えたり修正したりした記憶がなく困りました

# 解決方法

コメントしている位置が原因でした

これがAPIが表示されないコードで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/c706107a-ddc7-7868-36be-47e2c19cf963.png)

これが修正後のコードです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/3606056b-ae46-91f5-79d2-763a22b2c107.png)

コメントと関数の間に改行を

元記事を表示

GOのSwaggerでPostのFormデータを設定できるようにしたい

# はじめに

Goのgin-swaggerを設定する際にswaggerを始めて設定した私がつまづいた箇所があったのでまとめます

# 問題

gin-swaggerを利用してPOSTのAPIを登録しました
そのAPIでは`form-data`として`email`と`password`を受け取ります

いくつかの記事をみると`query`の設定の仕方は以下のようになっていました

“`
// @param none query string false “必須ではありません。”
“`

しかし、`form-data`を設定する方法がなかなか検索で出てこなかくて困りました

# 解決方法

Goは公式ドキュメントを読むと解決することが多く、今回はまさに[公式ドキュメント](https://github.com/swaggo/swag)に書いてありました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/ba0ca1b1-5272-59e5-8625-8e06f339fd2c

元記事を表示

GoのSwaggerでFailed to load API definitionエラーが発生する

# はじめに

仕事でGo開発を始めてREST APIのためにgin-swaggerを導入したのですが、記事通りにやってエラーが発生しました
そこで2度同じ現象につまづいたのでまとめていきます

# 問題

gin-swaggerを設定してブラウザを開いたところ以下の画面になりました

“`
Failed to load API definition
“`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/b9b5252d-3792-44a5-017a-6b13819c97a5.png)
[こちらから引用](https://www.thecodebuzz.com/resolved-failed-to-load-api-definition-undefined-swagger-v1-swagger-json/)

# 解決方法

これは`doc`をインポートしていないことで、swaggerがswaggerに関する設定ファイルを読み込めていないことで起きていました。

インポ

元記事を表示

【Go/Gin】手早くサイトを作るチートシート

# はじめに
とりあえず手早くサイトを作りたい、話はそれからだ、という人向けにGo, Ginを用いて手早くサイトを作るチートシートをここに残します。

# まずはGinのインストール
コマンドプロントで下記を入力。
“`
go get github.com/gin-gonic/gin
“`

# mainテンプレート
まずは基本骨格です。これをベースに味付けしていきます。
“`Go:main.go
package main

import (
“github.com/gin-gonic/gin”
)

func main() {
router := gin.Default()
router.LoadHTMLGlob(“templates/*.html”)

//トップページ
router.GET(“/”, func(ctx *gin.Context) {
ctx.HTML(200, “top.html”, gin.H{
})
})

router.Run()
}
“`
main.goと同じ階層にtemplatesディレクトリを作成し、その中に”top.ht

元記事を表示

OTHERカテゴリの最新記事