- 1. AtCoder Beginner Contest 196のメモ
- 2. yamlをインタラクティブに絞り込みできるCLIを作った
- 3. 2つの配列の要素を全部掛けて合計を求める
- 4. Go で Build Tool Mage を使う
- 5. プログラミング超入門(7)〜GO言語〜
- 6. Go のディレクトリ操作まわりの関数
- 7. 構造体に入門してみた
- 8. GolangでMeCab+NEologdが使えるDockerイメージ作成してみた
- 9. gqlgenでresolver・model・schemaファイルを分割しコードの見通しを良くする
- 10. 【Go言語】文字結合 (string concatenate) パフォーマンス strings.Builderを使おう
- 11. GoでO/Rマッパーと生SQLの違いを比較してみた
- 12. 【Go 言語】interface のポインタからメソッドコールできないのはなぜ?
- 13. Rustにおける「厳密な型付け」という文化
- 14. Rubyで理解するポリモーフィズムから、Goのインターフェースへ①
- 15. Golangでzipファイルを解凍する
- 16. Polymorphism with Interfaces
- 17. M5StickC Plus (ESP32) とTinyGoでLチカ
- 18. Goでnslookupする
- 19. deferに入門してみた
- 20. Golangで依存パッケージの脆弱性を調査するならNancyがおすすめ
AtCoder Beginner Contest 196のメモ
# 前置き
Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。# 問題
https://atcoder.jp/contests/abc196
# A
“`Q_A.go
package mainimport (
“fmt”
)func main() {
var a, b, c, d int
fmt.Scanf(“%d %d”, &a, &b)
fmt.Scanf(“%d %d”, &c, &d)e := a – c
f := a – d
g := b – c
h := b – dif (e >= f) && (e >= g) && (e >= h){
fmt.Printf(“%d\n”, e)
} else if (f >= e) && (f >= g) && (f >= h){
fmt.Printf(“%d\n”, f)
} else if (g >= f) && (g >= e) && (g >= h)
yamlをインタラクティブに絞り込みできるCLIを作った
## 初めに
最近仕事ですこしk8s周りを触っています。k8sのマニフェストはyamlですが、
kustomizeなどを使ってリソースをまとめたりすると、どうしても長くなってしまい可読性が下がってしまう問題があります。そこで、[jid](https://github.com/simeji/jid)のようなインタラクティブに絞り込みできるツールがほしいなと思って調べたんですが、
見つからなかったので[yd](https://github.com/skanehira/yd)というCLIを作りました。![](https://i.gyazo.com/521400d0740ed12c1606a8ab9b618632.gif)
## 使い方
`yd`ではパイプ、ファイル、URLからyamlを読み込めます。“`sh
$ yd file.yaml
$ yd https://sample.com/file.yaml
$ yd < file.yaml $ yd -f file.yaml ``` CLI実行後、画面上部にクエリを入力する箇所があるので、そこにクエリを入力してyamlをインタ
2つの配列の要素を全部掛けて合計を求める
# はじめに
配列$x$と配列$y$のそれぞれの全要素を掛けて合計を求めたい。
単純に書くと下記のようになる。“`golang
sum := 0
for _, xi := range x {
for _, yi := range y {
sum += xi * yi
}
}
“`
ループが二重になってしまい嬉しくない。# 改善
`xi`は内側のループ中は変化しないので、外に出してやればいい。
“`golang
sum := 0
for _, xi := range x {
sumy := 0
for _, yi := range y {
sumy += yi
}
sum += xi * sumy
}
“``sumy`は`x`とは無関係に求められるから、1回だけ計算すればいい。
“`golang
sumx := 0
for _, xi := range x {
sumx += xi
}
sumy := 0
for _, yi := range y {
sumy
Go で Build Tool Mage を使う
自分の参加しているプロジェクトで、Mage というビルドツールを使っている。私の環境では、Windowsを使っている人も多くて、私は、Go を書くときはLinux の shell 派なんだけど。普通のGoのリポジトリは Makefile のケースがが多いから、Windows派の人が困る、、、的な時に、結構よさげ。Go言語自体を使ってビルドツールが書けます。
* [Mage](https://github.com/magefile/mage)
* [Mage Go Doc](https://pkg.go.dev/github.com/magefile/mage/mage)
* [Mage.org](https://magefile.org/)通常は、Mageをとってきて、ブートストラップするのだけど、面倒なので、main.go を書いて、その中で、
_main.go_
“`go
func main() {
os.Exit(mage.ParseAndRun(os.Stdout, os.Stderr, os.Stdin, args()))
}func args() []s
プログラミング超入門(7)〜GO言語〜
#条件分岐
分岐処理とは、ある条件が満たされるときのみ特定の処理を行い、そうでなければ別の処理をしたり、また別のある条件が満たされているときのみ特定の処理を行い、そうでなければ何もしないなどといった与えられた式の値でtrueかfalseに分け異なる処理を行うようにすることをいいます。
##if文
`if 条件 { 条件を満たしたときの処理}`“`Branch1.go
package mainimport “fmt”
func main() {
age := 24if age >= 20 {
fmt.Println(“adult”)
}
}
“`
###実行結果
“`
adult
“`
##if~else文
`if 条件 A { 条件Aを満たしたときの処理} else { 条件を満たさないときの処理}`“`Branch2.go
package mainimport “fmt”
func main() {
age := 18if age >= 20 {
fmt.P
Go のディレクトリ操作まわりの関数
今回のトピックも自分のメモの色合いが強い。今回これを書いている理由は、「記憶するため」の一つの手段だ。
今回のお題はとても簡単で
ディレクトリを捜査して、Dockerfile にマッチするものを見つけてそのディレクトリにあるメタデータやディレクトリの名前を取得したいというとっても簡単なもの。問題は私が Go でどう書くかを記憶していないことにある。そこでブログを書いてみて整理してみよう。
# Current Directry
“`go
currentDir := os.Getwd()
“`# ファイルパスの結合
ファイルパスの結合はプラットフォームによって異なるので、自分で足すと暗黒。
Join のパラメータは、`…string` であるので可変長である。リストにも簡単に変換できる。“`go
path := filepath.Join(currentDir, “tests”, “images)
“`ちなみに、`…` は Ellipsis という。`[]string` から Ellipsis に変換したいケースは
“`go
param := [
構造体に入門してみた
おはようございます。(おそらく投稿するときは夜だと思いますが、、、)朝一で頭が冴えてる間に構造体について調べてみました。
この記事を書き始めている今時点の構造に対する認識は、
– いろんな型を持つ変数をひとくくりでまとめられる
こんなイメージです。
ドキュメントでは以下のように構造体が定義されています。
> struct (構造体)は、フィールド( field )の集まりです。
[https://go-tour-jp.appspot.com/moretypes/2](https://go-tour-jp.appspot.com/moretypes/2)
いや、そうなんだろうけどよくわからん!!って感じでした。
## やはりよくわからないのでいろいろ試してみます。
とりあえず構造体を使用してみます。
“`go
package mainimport (
“fmt”
)type User struct {
name string
age int
}func main() {
var me User
me.name = “endo”
me.age
GolangでMeCab+NEologdが使えるDockerイメージ作成してみた
#はじめに
社内のサーバーサイド公式言語である[Golang](https://golang.org/)で、
形態素解析ライブラリの`MeCab+NEologd`を試したいな〜
という情熱が燃えたぎったので、挑戦してみました。Dockerfile、初体験であります。(ドキドキ)
#TL;DR
– `main.go`の用意
– `docker-compose.yml`の用意
– `Dockerfile`の作成
– `startup.sh`の作成#`main.go`
[go gin](https://github.com/gin-gonic/gin)のフレームワークを使って、REST APIを作成し、テキストを受け取るとともにMeCabによる形態素解析の結果を返す`main.go`です。
(※エディタは`goland`を使いました。`Go Modules`とかの管理が楽)“`golang:main.go
package mainimport (
“fmt”
“log”
“net/http”mecab “github.com/bluele/mecab-gola
gqlgenでresolver・model・schemaファイルを分割しコードの見通しを良くする
gqlgenで開発していると、`gqlgen generate`で生成されるresolversとmodelsが長くなってしまい、分割したくなることがあると思いますので、その方法を書きます。
■方針
今回は、GraphQL形式でクライアントがDBのデータをリクエストすることを可能にするGraphQLサーバをGoで構築することが目的だったことから、schema、resolvers、modelsをテーブル単位で分割することにしました。## model分割
ここはドキュメント読めば分かると思うのですが一応書きます。
↓分割する際には`models_gen.go`にある構造体をテーブル毎にファイル分割して、あとは↓のように`gqlgen.yml`に書いておけば`go generate ./…`で新しく生成されなくなります。“`yml
models:
Users:
model: git-xxx/repository-name/graph/model.Users
“`## resolvers分割
一番分割したかったのがここ。ドキュメントを読んでも分割する方法が書
【Go言語】文字結合 (string concatenate) パフォーマンス strings.Builderを使おう
# TL;DR
go1.10からのstrings.Builderは実態はGoのBufferタイプと同じ。アロケーションが発生しないので多量な文字結合するならばstrings.Bufferを使っていこう。
# ベンチマークコード
“`go:vs_test.go
package mainimport (
“strings”
“testing”
)func Benchmark_string(b *testing.B) {
var s string
b.StartTimer()
for i := 0; i < b.N; i++ { s += "a" } b.StopTimer() } func Benchmark_stringsBuilder(b *testing.B) { var sb strings.Builder b.StartTimer() for i := 0; i < b.N; i++ { sb.WriteString("a") } _ = sb.String() // output string b.StopTimer() }
GoでO/Rマッパーと生SQLの違いを比較してみた
# はじめに
Ruby on Railsを学習している方はActiveRecordという名称のORマッパーを目にする事が度々あると思います。
私もプログラミングの学習をRubyから始めたのですが、ORマッパーと聞くとなんとなく「DBからのデータの取り出しを簡単にやってくれているんだな」くらいの認識でした。
Railsがあまりに様々な事をよしなにしてくれるので、Rails初学者の方は生のSQLを書く機会もほとんどないのではないかと思います。
最近Goを勉強し始めた事で、そのRailsがよしなにしてくれていた部分を基本から学び直す必要が出てきたので、ORMに関しても一つ学び直してここに備忘録として残したいと思います。# 対象者
– プログラミング初学者
– SQLは書いた事があるがORMは利用した事がない。あるいはORMは利用した事があるが生のSQLを書く事はあまりない。# 概要
Goのデータベースとのやり取りを、生のSQLで行った場合とORマッパーを利用した場合とでどうコードの違いが出るのかを比較して見ていきます。
Goを扱っていますが、簡単なコードなのでGoを触った事が無い方で
【Go 言語】interface のポインタからメソッドコールできないのはなぜ?
## 結論
簡潔に言うと「interface を指すポインタは interface を実装した構造体のポインタのポインタになるから」です。
これだけではよくわからないので詳しくみていきましょう。## interface のポインタからメソッドコールができないとは?
interface の Mammal とそれを実装した Human という構造体を考えましょう。
“`go
type Mammal interface {
GetAge() int
}type Human struct {
Age int
}func (h *Human) GetAge() int {
return h.Age
}
“`この時、以下のように Mammal というインターフェースのポインタから GetAge() をコールしようとするとコンパイルエラーになってしまいます。
“`go
func Foo(human *Mammal) {
_ = human.GetAge() // コンパイルエラー
}
“`GetAge() をコールするためには *Mammal ではなく
Rustにおける「厳密な型付け」という文化
# はじめに
Rustの特徴としてはメモリ安全性やGCなしで高速といったことがよく挙げられます。それらもRustの利点ではありますが、個人的に魅力を感じる部分の一つに「厳密な型付けをする文化」があると思っています。それはあまり明文化されておらず、個人的に感じているだけなのですが、Rustを使う動機の1つになりうると思うので、ここで宣伝してみます。
ちなみにこの記事のきっかけの1つが
[アンサー: なぜTypeScriptの型定義に凝るのか](https://qiita.com/uhyo/items/3bc5f951f922804ede51)
です。これを読んでいて、「自分はRustの型付け方針が好きなんだなぁ」とあらためて気づきました。
技術的な正確性より「気持ち」多めなのでポエムということで。# 「厳密な型付けをする文化」とは
Rustは静的型付き言語なので、ソースコード上の様々なところで型付けが行われます。これ自体は他の静的型付き言語と同様ですが、Rustではどのような型を付けるかということについて、比較的厳密に考える傾向があると思っています。
例えば標準ライブラリ
Rubyで理解するポリモーフィズムから、Goのインターフェースへ①
#何を書くか
私は現在、Go言語の学習に取り組んでいます。
そこで、**「インターフェース」**という概念を学びました。##何やこれ
正直、教本を読んでも全然なんのこっちゃと言った感じだったので、[こちら](https://qiita.com/k-penguin-sato/items/885a61d819cc431304f5)の記事を覗いてみました。すると
>interface(インターフェース) を利用することで、オブジェクト指向言語でいうところのポリモーフィズムと同様の機能を実現できます。
との説明がありました。ふむふむ。ポリモーフィズムね。
何だそりゃ。
##ということで
Rubyの学習も兼ねて、まずはオブジェクト指向のポリモーフィズムを理解し、それからインターフェースを学習していこうと思います。一応二部作の予定で書いていきます。
1部目の今回は、**ポリモーフィズム**について、自分が調べただけつらつらとお話ししていこうと思います。#ポリモーフィズムとは
**オブジェクト指向言語(Rubyが持つプログラミング言語が持つ概念的な捉え方)**には、守べき設計
Golangでzipファイルを解凍する
こんにちは。初投稿です。どうぞお手柔らかにm(__)m。
Go言語に触れ始めて数か月、それほどガッツリ書いてるわけではないですが、少しわかってきた気がします(危険な時期)
さて、タイトルの通りZipファイルを解凍するのですが、よくあるZip解凍ツールのように「ファイル名を展開先のディレクトリ名に使う」のってよくありませんか?ないですかそうですか。
例えば「test20210318.zip」であれば「test20210318」というディレクトリを作って、その下層に展開する、というものです。
実際に業務でニーズがありまして、同じファイル構成でzip圧縮されたファイル群を、繰り返し解凍するような仕組みです。作ったサンプルがこちら。
“`Go:sample/unzip/main.go
package mainimport (
“archive/zip”
“fmt”
“io”
“os”
“path/filepath”
“regexp”
)// unZip zipファイルを展開する
func unZip(src, dest string) error {
r,
Polymorphism with Interfaces
https://play.golang.org/p/ojRqAxy5JYm
https://medium.com/technofunnel/polymorphism-with-golang-interfaces-b2f58a05b221
# work
“`
package mainimport (
“fmt”
)type Test interface{
Run()
// Debug()
}type My struct{
body string
}func (m My)Run(){
fmt.Println(m.body)
}func main() {
my := &My{body: “DOOOOOOOO”}
fmt.Println(“Hello, playground”)
testRun(my)
}func testRun(t Test){
t.Run()
}“`
↓
“`
Hello, playground
DOOOOOOOO
“`# Error
“`
package mainimport (
“fmt”
M5StickC Plus (ESP32) とTinyGoでLチカ
# はじめに
最近、仕事でGO使ってて、趣味ではESP32を使ってるので、TinyGoでESP32をプログラミングしたくなってきた。ということで、Lチカすることにした。# 環境
macOS Big Sur Ver 11.1# インストール
## TinyGo
tinygoは、ここを参考にして、インストールした。
[macOS :: TinyGo – Go on Microcontrollers and WASM](https://tinygo.org/getting-started/macos/)いろいろ書かれてるけど、これだけで動くはず。
“`zsh
brew tap tinygo-org/tools
brew install tinygo
“`## ESP32のためのツール群
これにしたがって下記ツールを入れた。[ESP32 – mini32 :: TinyGo – Go on Microcontrollers and WASM](https://tinygo.org/microcontrollers/esp32-mini32/)
– pyserial
Goでnslookupする
“`golang
package mainimport (
“fmt”
“log”
“net”
)func main() {
addr, err := net.LookupHost(“vamdemicsystem.black”)
if err != nil {
log.Fatal(err)
return
}
fmt.Println(addr)
}
“`“`
⋊> /t/golang go run main.go 23:06:26
[183.181.88.32]
“`
deferに入門してみた
# deferに入門してみた
ちょっと退屈してたたので、deferについて調べてまとめてみます。
この記事を書き始めている今時点のdeferに対する認識は、
– 処理を実行を遅らせてくれる便利なやつ
– どこで実行しても最後に処理してくれるから、忘れてた!!ってことを防止できるやつこんなイメージを持ってます。
## では早速ごちゃごちゃ動かしてみます。
“`go
package mainimport (
“fmt”
)func main() {
defer fmt.Println(“defer Hello, playground”)
fmt.Println(“Hello, playground”)
}
“`実行結果
“`
Hello, playground
defer Hello, playground
“`イメージした通り、処理が遅れましたね。
では、deferが2つあったときは??
“`go
package mainimport (
“fmt”
)func main() {
defer fmt.Println(“def
Golangで依存パッケージの脆弱性を調査するならNancyがおすすめ
# 概要
* Goで使用する外部パッケージが安全かどうかを調べる時にオススメなのが、[nancy](https://gonancy.dev/)です。
* ちなみにnancyとは、Sonatype OSS Indexを利用して、Golangの依存関係の脆弱性をチェックするツールです。
* nancyではdepまたはgo modの依存関係を調査してくれます。![nancy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/79fec195-ab17-3383-03db-e5319d156c58.png)
# 導入方法
* install方法“`
> brew tap sonatype-nexus-community/tap
> brew install nancy
“`# 試す
* helpを見てみる
* 見てみると、引数にGopkg.lockまたは、go.sumのpathを指定してあげるようです。“`
❯ nancy –help
Usage:
nancy [opti