Go関連のことを調べてみた

Go関連のことを調べてみた

【Go言語】スキルチェックを解くための開発環境とコーディングの考え方

# 概要

コラボキャンペーンが面白そうなので、久しぶりにPaizaの問題を解いてみました。

せっかくなので、ローカルの環境でもテストができる環境構築も整え、解説してみようかと思います。
少し前まで、Paizaのエディターで直接書いて提出していました。もちろんテストなしでした(笑)

提出コードは Go言語を使用しています。(私の一番得意な言語なので)

## 想定する読者

– 就職活動でPaizaを利用している人
– エンジニアになってまだ経験が浅い人

## この記事の目的

– Paizaのスキルチェックを受け、エンジニアへの就職(転職)を成功させる

## この記事で解説すること

– 実務のコードと競技プログラミングのコードの考え方
– Paizaの問題をローカル環境で書いて試す

ローカルでの開発環境を整えることで、より効果的、効率的にPaizaのスキルチェックを受ける。
ただスキルチェックを受けるだけでなく、企業の目に止まりやすいコーディングができるようになる。
これらを目指して、就職(転職)を成功させてほしいと思います。

## この記事では解説していないこと

元記事を表示

goのエラーハンドリング

実用Go言語 第5章 エラーハンドリング より

### エラーハンドリングの基本
エラーハンドリングとしては多くの場合以下のような方針が考えられる。
1. 呼び出し元に関数の引数などの情報を付与してエラーを返す
2. ログを出力して処理を継続する
3. リトライを実施する
4. リソースをクローズする

Goではpanicを多用せずエラーハンドリングを行いエラーを返すべき。

### 呼び出し元に情報を付与して返す
エラーが発生した場合そのまま返していては発生個所の特定がむずかしいため、情報を付加して返す。
“`
user, err := getInvitedUserWithEmail(ctx, email)
if err != nil {
return fmt.Errorf(“fail to get invited user with email(%s): %w”, email, err)
}
“`

### ログを出力して処理を継続
ex. データベースに指定されたレコードが存在しないとデフォルトの値を用いて処理を継続するなど
“`
//func featchCap

元記事を表示

goのエラー作成

実用Go言語 第五章 エラーハンドリングよりメモ

goアプリケーションでエラーを作成する方法は大きく二つに分けられる。

1. 標準ライブラリの関数を使って作成
2. アプリケーション独自のエラー型を定義

### errors.new
もっともシンプルなエラー生成法。変数に保存すると区別してハンドリングしやすい。
“`
var ErrNotFound = errors.New(“not found`)
func findBook(isbn string) (*Book, error) {
return nil, ErrNotfound
}
“`

### fmt.Errorf
フォーマットされた文字列を元にエラーを作成
“`
func validate(length int) error {
if length <= 0 { return fmt.Errorf("length must be greater than 0, length = %d", length) } return nil } ``` ### 独自のエラー型

元記事を表示

gormを使ったクエリーのロギング

実用Go言語 9.9.4 クエリーのロギングより メモ

– 標準ライブラリのdatabase/sqlパッケージはロギングをサポートしていない
– サードパーティ側で用意されている場合積極的にライブラリ側のAPIを使うとよい

“`
newLogger := logger.New(
log.New(os.Stdout, “\r”, log.LstdFlags), //出力設定、改行方法、プロパティ
logger.Config{LogLevel: logger.Info}, //Silent, Error, Warn, Info がある
)

db, err := gorm.Open(sqlite.Open(“test.db”), &gorm.Config{Logger: newLogger})
if err != nil {
log.Fatal(err)
}
“`

※log.LstdFlags とは
logを yyyy/mm/dd HH:MM:SS で表示する。
他にもLmicrosecondsマイクロセカンド表示などがある

表示されたログ
“`

元記事を表示

gqlgenのDirectiveだけでフィールドの値をフィルタリングする

gqlgenのバージョンはv0.17.42です。
結構ググったのですが、タイトルに書いた目的をスマートに実現している例が見つからなかったので。
どなたかの参考になれば幸いです。

#### スキーマ
“`graphql
directive @isAuthenticated on FIELD_DEFINITION | OBJECT
directive @onlyAdmin on FIELD_DEFINITION | OBJECT

type Account {
id: ID!
name: String!
thisIsSecret: String @onlyAdmin # この記事で伝えたいのはこれ
created: DateTime!
updated: DateTime!
}

extend type Query {
currentAccount: Account @isAuthenticated
}
“`

#### ディレクティブの実装
“`go
package direcrive

import (
“context”
“reflect”
“st

元記事を表示

Cloudbuildとgoのginを使用してCloudRunとcloudFunctions(gen2)へデプロイする

## ディレクトリ構造
“`
./
├─/cmd
│ └── main.go
├─/handlers
│ └── handlers.go
├── Dockerfile
├── go.mod
├── go.sum
├── cloudbuild.yaml
└── router.go
“`
## goのソース
“`main.go
package main

import (
“context”
“log”

router “github.com/yourname/gin”

“github.com/GoogleCloudPlatform/functions-framework-go/funcframework”
)
func main() {

ctx := context.Background()

gin := router.GinHandler

// 実行する関数の登録
if err := funcframework.RegisterHTTPFunctionContext(ctx, “/”, gin); err != nil {
log.Fatalf(“fu

元記事を表示

キー一発でOCR+Linterかけてコマメに日本語をメンテナンスするツール書いた!

# 日本語の乱れはコンテキストの乱れ

日本人だけど日本語力に乏しいと言われ続けて生きてきました・・・

「~の、~の、って二度出てきて読み辛い」
「実装を行う、じゃなくて、実装するで良いんじゃない?」
「アプリなのかい?アプリケーションなのかい?どっちなんだい?」

みなさんも経験があると思うけど、こういう些細なミスは口語だったら言い直しと説明で済む。
でも、資料だけを見て、内容を判断しなきゃならない場合誤読を呼び込んでしまう。
「てにおはを正しく!」って昔、先輩に言われてた事、そういう事だって良いオジサンになってから思い返してる。
読み辛い文はコンテキストを乱し、伝えたいメッセージを弱めてしまう、そういうことだったのサ!

**リンター入れますか?**

# リンター入れられません・・・

Markdownとかテキスト形式ならtextlint使うなりのエコシステムに乗っかれた。
でもそうはいかない状況はしばしば発生する・・・

– Powerpoint
– ブラウザのスプシ
– PDFとかリッチなフォーマット
– そもそも画像フォーマット

元ソースがテキスト文章に寄せてないフォー

元記事を表示

【地図】日本の市区町村ごとの犯罪率/賃貸/年収/人口のステータスが一覧できるWebサイトを作りました。【個人開発】

# 1.概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201311/7d141c74-2cff-c27e-8e46-1fe866940383.png)

– サイト名: 日本まとめ地図
– URL: https://prod.jpn-map-status.com/

「日本地図ステータス」は、日本の各都道府県のさまざまな統計情報を視覚的に表示するウェブサイトです。このサイトは、次のような特徴を持っています。

1. Leafletを使って視覚的に情報を表示しています。
– 地図ライブラリはフリーのleafletを使用しています。
2. 各市区町村ごとにステータス16段階色分け
– 平均年収・賃貸・人口密度・治安で順位づけしてます。
– 治安は1000人あたりの犯罪認知件数から算出
– ヘッダーのメニューから項目の切り替え
3. 各地域をクリックすることで詳細を表示
– 具体的な数値を表示

**情報元**
政府統計ポータル[e-St

元記事を表示

ProxmoxをiPXEでいれてみた

## 概要
ProxmoxをiPXE経由で起動して自動セットアップをしてみる

## 流れ
1. iPXEBoot可能なPCを起動する
1. DHCPによりインストーラの場所を取得
1. HTTPサーバーよりインストーラの取得
1. 同じくHTTPサーバーより初期セットアップ用の回答ファイルの取得
1. 自動起動!

## 環境
| 機器 |
|——|
|NEC IX2215|
|動いてるPROXMOXサーバー 8.1.4|

## 手順
#### iPXEBoot可能なPCを準備する
検証につき自前proxmoxサーバーにてVMを準備
マシン: i440fx
BIOS: SeaBIOS
OSタイプ: Linux 6.x
CPU: HOST
メモリ: 6,144

:::note warn
メモリが6GB以下だとインストールができないことがあった
:::

一度起動し、BIOS設定にて起動順序を`iPXE ipv4` のみにしておく

#### インストーラの準備
https://pve.proxmox.com/wiki/Automated_Installation
ここを参考

元記事を表示

GORM Saveメソッドの挙動を追ってみた

#### GORMのsaveメソッドはupsertをやってくれて便利だが、update時にCreatedAtは更新されるのか?あれupdateなのになんかinsert動いてない?みたいなことがあって調べた

## 知ってないとハマるポイント1
#### SaveメソッドはUpdateして0件だとINSERTするよ

ちょっと意外だったのが、Updateを実行した際に結果が0件だと、INSERTが実行されます。
これは便利ともいえるけど、何らかのバグでプライマリフィールドに意図しないIDが渡るとエラーにならずに、レコードがINSERTされてしまいます。

https://github.com/go-gorm/gorm/blob/master/finisher_api.go#L73

“`go:finisher_api.go
func (db *DB) Save(value interface{}) (tx *DB) {
tx = db.getInstance()
tx.Statement.Dest = value

reflectValue := reflect.Indir

元記事を表示

Dockerでgoのマルチステージビルドでexisted(0)で落ちる件を解決した

## 初めに
筆者はDocker初心者であんまりDockerについて理解してません。ご了承ください

## 結論
必要なファイルは実行用コンテナにもコピーしよう
“`dockerfile
COPY –from=builder /app/config ./config
“`

## 経緯
– あるプロジェクトでgoの環境を作る必要があった
– 容量が1GB近くとかなり大きいイメージだった
– CI/CDを意識すると容量を削減したいと考えていました

## マルチステージビルド
調べていく中でマルチステージビルドというものがあるのを発見
これを使おうとしました
## existed(0)の症状
– マルチステージビルドを使わない環境だと立ち上がる
“`dockerfile
FROM golang:1.20-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /main ./cmd
“`
– マルチステージビルド環境で立ち上がらない
“`dockerfil

元記事を表示

【Go】Ginでhealth_checkのログを表示したくない

# はじめに
health_checkのログが多すぎて大事なログが見つけられない…みたいなことありますよね。
Ginの環境を作っている際にその問題にぶち当たったので、そんなお悩みを解決できる方法を備忘録としてまとめました。

# 結論
以下の2通りの方法で、特定のパス(ここでは/health)についてログ出力を抑制することができます。
“`go
router := gin.New()
router.Use(gin.LoggerWithWriter(gin.DefaultWriter, “/health”))
router.Use(gin.Recovery())
“`

“`go
router := gin.New()
router.Use(gin.LoggerWithConfig(gin.LoggerConfig{SkipPaths: []string{“/health”}}))
router.Use(gin.Recovery())
“`

通常、基本的なルーターの設定にはgin.Default()を使用することが多いと思います。
この関数はデフォルトで`Logger`と

元記事を表示

Go構造体のバリデーション: スペースの落とし穴

# はじめに
ウェブアプリケーションを開発する際、HTTPメッセージボディのデータの検証を行う場合があります。
例えば、ユーザーが入力した情報が必須項目を満たしているか、数値が適切な範囲に収まっているかなど。
Go言語でバックエンド開発を行うときには、構造体を使用したバリデーションが一般的です。

## Go言語でのバリデーション
Go言語では構造体を定義しそのフィールドに対してバリデーションルールを設定することができます。これにより、データの一貫性と正確性を確保し、エラーを未然に防ぐことができます。

“` struct.go
type Person struct {
Name string `json:”name” binding:”required,min=3″`
Age int `json:”age” binding:”required,min=0,max=100″`
}
// required: `Name`, `Age`共にフィールドは必須で、空の値は許可されない
// min=3: `Name`フィールドの値は最低でも3文字以上でなければならない

元記事を表示

GORMでUpdateするメソッドについて表に整理してみた

gormのUpdateメソッドについてそれぞれ違いがあるので表にまとめてみた。

### GORMの更新メソッドの違い

| メソッド | 更新対象 | `UpdatedAt`の自動更新 | ゼロ値の扱い(数値型の0、空文字、boolのfalse など) | 主な用途 |
|——————|—————–|———————-|————————————————-|——————————-|
| `Save` | 全フィールド | する | 更新される | 全フィールドの更新、新規レコードの保存 |
| `Update` | 単一フィールド | する

元記事を表示

URLからQRコードを生成するアプリを作ろう

## はじめに

初めましての人もそうでない人もこんにちは!

最近就活を始めたという人はそこそこいるのではないでしょうか?
最近ではオンライン面接というものが増えてきていてZOOMやGoogleMeetを使って面接する企業も少なくありません!

おそらくこれを見ているあなたは面接の始めの方で「あなたの自己紹介(自己PR)をお願いします。」と聞かれた経験はあると思います!

自己紹介のやり方は様々ですが私は自己紹介スライドを用意してそのスライドを使って画面共有をしながら紹介をしています!

その中にこのQiita記事やGithubなどのQRコードを入れることでわざわざリンクをコピペせずともカメラ機能だけで見ていただくことができるようになるのでとても良いのではないでしょうか?

「書類選考の時にQiitaとかGithubのURLは出しているよー」という場合は書類選考の時に書くことができなかった他の自己PRできるものをQRコードにすれば良いのではないでしょうか?

しかしインターネット上に転がっているQRコード作成ツールを使って自分の情報が入ったサイトのURLを入れることに抵抗感があるひと

元記事を表示

サポーターズ(Docker)イベントに参加 2024.07.23

本日もサポーターズのイベントに参加した。

内容は、初心者向けのDockerについての解説とアウトプットの実施であった。

## Dockerとは
コンテナ型の仮想環境を気軽に構築、実行できるプラットフォーム。
Dockerはチーム開発にとても向いている。なぜなら、全く同じ環境で作ることができ、削除も簡単なためである。

ゲストOSは必要なく、ホストOS上で作成できる。ホストOSは仮想環境を動かす土台となっているOSである。
自分のPCのOSはWindowsなので、ホストOSはWindowsである。

イベントの中で注目していた3つのワードについての解説もあった。

## イメージ
イメージとは、コンテナを作るための設計図で、プロジェクトの名前、使用する技術のバージョンの指定などが記されている。

## コンテナ
コンテナとは、アプリケーションの実行環境のことで、プロジェクトのようなものである。
コンテナを作成、起動、削除が可能である。

## ボリューム
データの永続化を担う場所であり、外部HDDのようなもの。ボリュームを使わずにコンテナを削除するとデータが消えてしまうので、コン

元記事を表示

GORM UpdateColumnsはUpdatedAtを更新しない

## メモ
gormのUpdateColumnsはUpdatedAtを更新しない。
その仕組みを実際のコードとともに整理してみた。

その他のUpdateメソッドの挙動はついでに以下に整理した。
https://qiita.com/yukiyoshimura/items/a6fa5ac9ff1bd8d03be5

## 背景
gormの `UpdateColumns`を使っていたところUpdatedAtが更新されてないことに気づいた。
以下にHookメソッドをスキップするときに使ってねみたいなのが書いてある。Hookメソッド内でUpdatedAtを更新しているのだろうか・・・ちょっとはっきりしたものは見つけられないが、フックをスキップしているところを追ってみる。
https://gorm.io/docs/update.html#Without-Hooks-x2F-Time-Tracking

### 実際にコードをみてみる
UpdateColumnsの処理をみる。
`tx.Statement.SkipHooks = true` でskipセットしている。
https://github

元記事を表示

【Paiza】山折り谷折り (paizaランク A 相当)をGo「Template」で解いた【text/template】

:::note warn
この記事は、「paiza×Qiita記事投稿キャンペーン」のキャンペーン対象問題の解説記事です。
**通常の「paizaスキルチェック問題」の解答公開は禁止されています** のでご注意ください。
:::

Go Templateだけでスキルチェックを突破しようとする ~~実用性0の~~ 記事2本目です。前回の記事はこちら。

https://qiita.com/Syuparn/items/de5f3a4b5bba41f4959c

# 解答

ソースコード(クリックで開く)

“`go
package main

import (
“bufio”
“os”
“text/template”
)

var tmplStr = `
{{- define “writeZero” -}}
{{- if ge (len $) 1 -}}
{{- $next := (slice $ 1) -}}
{{- template “writeZero” $next -}}
{{- print “0” –

元記事を表示

echoを使ったAPIキー認証のサンプル

# 概要
echoの使い方を勉強してみるがてら、APIキーによる認証を作ってみようと思い取り組んでみました。
APIキーによる認証の考え方がGCPのドキュメントにまとめられていたのでリンク置いときます。

https://cloud.google.com/endpoints/docs/openapi/when-why-api-key?hl=ja

# やってみた
リクエストヘッダに `X-API-KEY` としてAPIキーが付与されるものとして、curlで以下のようなリクエストを送る想定です。
“`bash:ターミナル
curl -H ‘X-API-KEY:testkey’ localhost:8080/hello
“`

## echoのミドルウェアを使ってみる
“`go:main.go
package main

import (
“net/http”

“github.com/labstack/echo”
“github.com/labstack/echo/middleware”
)

func main() {
e := echo.New()
// APIキーチ

元記事を表示

【Paiza】長テーブルのうなぎ屋 (paizaランク B 相当)をGo「Template」で解いた【text/template】

:::note warn
この記事は、「paiza×Qiita記事投稿キャンペーン」の **キャンペーン対象問題** の解説記事です。
**通常の「[paizaスキルチェック問題](https://paiza.jp/challenges)」の解答公開は禁止されています** のでご注意ください。
:::

# TL; DR

https://paiza.jp/works/mondai/b_rank_skillcheck_sample/long-table

“`
{{- /* 座席の初期化 */ -}}
{{- $seats := “” -}}
{{- /* nSeats <= 100 なので、100回のループをnSeats回で打ち切れば 長さ nSeats の文字列が得られる */ -}} {{- range $i, $_ := $.Looper -}} {{- if ge $i $.NSeats -}} {{- break -}} {{- end -}} {{- $seats = print $seats " " -}} {{- end -}} {{- /* グループを

元記事を表示

OTHERカテゴリの最新記事