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

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

Go + YouTube Data API v3 で特定のチャンネルの動画データ一覧を取得する

# 目的
YouTube Data API v3を使って、特定のチャンネルにアップロードされた動画に関するデータをすべて取得することが目的です。
APIの仕様上取得できる件数に制限があったり、動画のIDであるVideoIdの一覧を取得する際にちょっと苦労ので、それらを中心に解説していきますが、基本的には以下のリファレンスを見れば、時間はかかるかもしれませんが大体の操作は簡単に実装できるかと思います。
[YouTube API Reference](https://developers.google.com/youtube/v3/docs?hl=ja)

# 前提
* Go言語を使える環境が前提です
* 使っているバージョンは `1.18.3`
* 以下の記事を参考に、YouTube Data API v3を有効にし、APIキーが取得済み
[YouTube Data API v3 を使って YouTube 動画を検索する](https://qiita.com/koki_develop/items/4cd7de3898dae2c33f20)

# 流れ
私のGitHubページに以下の一

元記事を表示

小ネタ/Open API 3.0 ジェネレータ oapi-codegen v1.11.0 のコード自動生成の方法

社内で使う管理用のちょっとした API を OpenAPI & Go(golang) で作るべく **[oapi-codegen](https://github.com/deepmap/oapi-codegen)** を(過去の文献を参考に)使おうとして、

`configuration error: package name must be specified`

に阻まれ、回避方法を探したら **[リリース情報のページ](https://github.com/deepmap/oapi-codegen/releases/tag/v1.11.0)** にちゃんと書いてあった、というだけのメモ書きです。

(ついでにいうと、最初に探し当てていた文献にもちゃんと書いてありました…)

## 以前のバージョンでの使い方

こんな感じで紹介されている例が多かったと思います。

“`sh:
go get github.com/deepmap/oapi-codegen/cmd/oapi-codegen
oapi-codegen 【スキーマ定義の .yaml ファイル】 -package 【パッケ

元記事を表示

【自己学習】Go言語を学ぶ(8)

# 公式チュートリアルから基本を学ぶ
https://go-tour-jp.appspot.com/list

## Switch
switch 文は if – else 文のシーケンスを短く書く方法です。

サンプルコード:実行したOSを調べる

“`go
package main

import (
“fmt”
“runtime”
)

func main() {
fmt.Print(“Go runs on “)
switch os := runtime.GOOS; os {
case “darwin”:
fmt.Println(“OS X.”)
case “linux”:
fmt.Println(“Linux.”)
default:
// freebsd, openbsd,
// plan9, windows…
fmt.Printf(“%s.\n”, os)
}
}
“`

## Switch evaluation order(評価順序の切り替え)
switch caseは、上から下へcaseを評価し

元記事を表示

【自己学習】Go言語を学ぶ(7)

# 公式チュートリアルから基本を学ぶ
https://go-tour-jp.appspot.com/list

## If文

* Go言語の if 文は、先ほどの for ループと同様に、括弧 ( ) は不要で、中括弧 { } は必要です。

サンプルコード:

“`go
package main

import (
“fmt”
“math”
)

func sqrt(x float64) string {
if x < 0 { return sqrt(-x) + "i" } return fmt.Sprint(math.Sqrt(x)) } func main() { fmt.Println(sqrt(2), sqrt(-4)) } ``` 実行結果:1.4142135623730951 2i ## If with a short statement(if文を短くした場合) if 文は、 for のように、条件の前に、評価するための簡単な文を書くことができます。 ここで宣言された変数は、 if のスコープ内だけで有効です。 サンプルコ

元記事を表示

Golang Generics について

# 概要
Golang での Generics に関する知見をまとめた記事になります。

## Generics とは?
> ジェネリック(総称あるいは汎用)プログラミング)は、具体的なデータ型に直接依存しない、抽象的かつ汎用的なコード記述を可能にするコンピュータプログラミング手法である。

Golang では[1.18](https://tip.golang.org/doc/go1.18#language)からGenericsを利用できるようになりました。

**引用元**
– [ジェネリックプログラミング](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

# 比較
[公式のドキュメント](https://go.dev/doc/tutorial/generics)を元にGenerics有無のソースコードの比較と書き方を確認します

#

元記事を表示

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

元記事を表示

OTHERカテゴリの最新記事