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

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

【#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

元記事を表示

Goで go invalid memory address or nil pointer dereference エラーが発生する

# はじめに

最近Goを仕事で初めて、色々な記事を参考にREST APIを作成していました
そこで変数のポインタに関するエラーが発生したのでまとめます

初心者ならやりそうなミスだと思うので多くの方の参考になればと思います

# 問題

以下のコードで変数DB(gorm)の初期設定を行いました

“`go:base.go
var DB *gorm.DB
var err error

func init() {
checkDB()
dsn := config.Config.DBName
DB, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalln(err)
}
migrate(DB)
}
“`

そしてそこで設定した変数DBを利用して以下の関数でユーザーを取得します

“`go:user.go
func GetUserByEmail(e string) User {
user := User{}
DB.Where(“Email = ?”, e).First(&

元記事を表示

高級言語で`string`とか`slice`を使う際に気をつけている効率化のためのTips

## この記事は

株式会社Nucoで golang でバックエンド開発をやっているhitoshi44と申します。

Qiitaの記事を書いてくれと言われたので、自分がコードを書くときにちょっとこだわっていることをTipsにしてみます。
カレーはルーが右で福神漬けが奥みたいなレベルのこだわりですが参考になれば幸いです。

slice型 (と実質的なsliceである`string`型)を扱う時にこうするとエコだよねと言う話です。

言語は今業務で使っている golang を例に出しましたが、言語によらない話です。

## `slice`型(と`string`型)の仕組み

`slice`型は本質的には動的配列を覗くための窓のようなものですが、まずはどんな仕組みになっているか見てみましょう。

golang, Rustの`slice`型はECMAScriptだとDataViewが近いです。
またほとんどの言語で`string`は`slice`の兄弟のようなものです。

“`go
data := []int{1,2,3}
“`

この時、変数 `data` はこんな形をしています

`

元記事を表示

Serverless frameworkでGoをデプロイしたらPath errorが発生する

# はじめに

この記事は2022年8月にまとめていた「細かいつまずいたことをメモしておく(8月編)をそれぞれ投稿した内容になります
解決方法が最新でない可能性もありますのでご了承ください

# 問題

https://blog.mmmcorp.co.jp/blog/2020/06/07/aws-lambda-with-golang-gin/

https://zenn.dev/sti320a/articles/f60aa3ef305075

この記事をみて設定をしていたがいざデプロイすると以下のエラーが発生

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/982f825a-772f-921b-3286-d61806242e96.png)

# 解決方法

“`Makefile
build:
go mod download
env CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags=”-s -w” -o bi

元記事を表示

Goでgooseコマンドを打っても実行できない

# はじめに

この記事は2022年8月にまとめていた「細かいつまずいたことをメモしておく(8月編)をそれぞれ投稿した内容になります
解決方法が最新でない可能性もありますのでご了承ください

# 問題

“`
$ go install github.com/pressly/goose/v3/cmd/goose@latest
“`

https://github.com/pressly/goose

で`goose`をいれて、`goose status`を叩いても実行ができず`goose help`と同じ内容がでる
/dbに`dbconf.yml`を設定しているがそれが読み込まれていないようだった

# 調査

以下のコマンドでgooseを実行すると成功した

“`
$ goose mysql “root:password@tcp(db:3306)/techblog?parseTime=true” status
“`

これは

“`
goose mysql “ユーザー名:パスワード@tcp(ホスト名:3306)/DB名?parseTime=true
“`
と読み替える

元記事を表示

OTHERカテゴリの最新記事