20201012のGoに関する記事は5件です。

Golangのflagパッケージの使い方(最小限の知識)

flagパッケージはコマンドラインのフラグを解析するのに便利なパッケージです。

flagパッケージをインポートする

import "flag"

フラグの値を格納する変数を定義する

関数外で定義する場合の書き方

後述するinit()のXxxVar()で変数にバインドする場合はフラグを格納するための変数を用意する。

var boolFlag bool
var intFlag int
var strFlag string

関数内で定義する書き方

後述するinit()のXxxVar()で変数にバインドしなかった場合はポインタとなる。

  boolPtr := flag.Bool("b", false, "真偽値の値の例")
  intPtr := flag.Int("i", 0, "数値の場合の例")
  strPtr := flag.String("s", "", "文字列の場合の例")

フラグの初期化

init() はmain()が呼ばれる前に実行される。
main内に記述したflag.Parse()によって変数に指定されたフラグの値が入るが、initの時点ではまだ変数には値が入っていない状態。
そのためここではフラグの値を格納するためのポインタを予約するだけの挙動となる。
XxxVar()で変数にバインドする。引数には変数のポインタ、フラグの名前、デフォルト値、使い方の説明を記述する。

func init() {
  flag.BoolVar(&boolFlag, "b", false, "真偽値の値を指定")
  flag.IntVar(&intFlag, "i", 0, "数値の値を指定")
  flag.StringVar(&strFlag, "s", "", "文字列の値を指定")
}

フラグの解析と取得

flag.Parse()を呼ぶことでコマンドラインの引数のフラグが解析され、フラグが変数にバインドされる。

flag.Parse()

これ以降、変数からフラグの値を取得できるようになる。

コマンドラインでの実行例

ソースファイルから実行する場合

# フラグの指定なし
go run flagsample.go

# フラグの指定あり
go run flagsample.go -b
go run flagsample.go -b -i=1 -s=a

バイナリファイルから実行する場合

# プログラムをコンパイルし、
go build flagsample.go
# その後バイナリを実行する。
./flagsample -b -i=1 -s=a

ソースの全体像

関数外で定義する場合の書き方

package main

import (
  "flag"
  "fmt"
)

var boolFlag bool
var intFlag int
var strFlag string

func init() {
  flag.BoolVar(&boolFlag, "b", false, "真偽値の値の例")
  flag.IntVar(&intFlag, "i", 0, "数値の場合の例")
  flag.StringVar(&strFlag, "s", "", "文字列の場合の例")
}

func main() {
  flag.Parse()

  fmt.Println(boolFlag)
  fmt.Println(intFlag)
  fmt.Println(strFlag)
}

関数内で定義する書き方

package main

import (
  "flag"
  "fmt"
)

func main() {
  boolPtr := flag.Bool("b", false, "真偽値の値の例")
  intPtr := flag.Int("i", 0, "数値の場合の例")
  strPtr := flag.String("s", "", "文字列の場合の例")

  flag.Parse()

  fmt.Println(*boolPtr)
  fmt.Println(*intPtr)
  fmt.Println(*strPtr)
}

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Golangのerrorとpanic

The art of programing

業務ロジックにエラーブロックが沢山の場合がよく見られる
例えば以下の関数を順次に呼ぶ

func first() error {return nil}
func second() error {return nil}
func third() error {return nil}
func fourth() error {return nil}
func fifth() error {return nil}

errorを判断する書き方は、
なに?眩暈しちゃった。。。

func Do() error {
    var err error
    if err = first(); err == nil {
        if err = second(); err == nil {
            if err = third(); err == nil {
                if err = fourth(); err == nil {
                    if err = fifth(); err == nil {
                        return nil
                    }
                }
            }
        }
    }
    return err
}

実際の仕事にはフラットな方が多くて、

func Do() error {
    var err error
    if err = first(); err != nil {
        return err
    }
    if err = second(); err != nil {
        return err
    }
    if err = third(); err != nil {
        return err
    }
    if err = fourth(); err != nil {
        return err
    }
    if err = fifth(); err != nil {
        return err
    }
    return nil
}

さ、panicを使えば、

func Do2() (err error) {
    defer func(){
        if r:= recover() ; r!= nil{
            err = fmt.Errorf("Error: %+v", r)
        }
    }()
    first2()
    second2()
    third2()
    fourth2()
    fifth2()
    return
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Qiita APIをgoから叩いてみた

はじめに

Go言語を勉強しなければという使命感にかられ、遊んでみることにしました。

golang + Qiita API

環境

・ go version go1.13 darwin/amd64

URIと機能

Path HTTPメソッド 機能
/qiita/api/v1/user-info GET 指定されたユーザの記事一覧を、作成日時の降順で返します。

使用パッケージ

・ gin
ginは、go製のWebフレームワークです。jsonレスポンス処理機能も持っている優れものです。

go get github.com/gin-gonic/gin

ファイル構成

❯ tree .
.
├── main.go
└── src
    └── controller
        └── controller.go

2 directories, 2 files

controller

mainから呼び出すタスク処理をまとめています。

controller.go
package controller

import (
    "encoding/json"
    "io/ioutil"
    "log"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
)

type Item struct {
    Title     string    `json:"title"`
    CreatedAt time.Time `json:"created_at"`
}

// Qiita APIを叩く
func QiitaGET(c *gin.Context) {
    resp, err := http.Get("http://qiita.com/api/v2/users/{自身のアカウント名}/items?page=1&per_page=10")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    var data []Item

    if err := json.Unmarshal(body, &data); err != nil {
        log.Fatal(err)
    }

    c.JSON(http.StatusOK, gin.H{"item": data})
}

main

メイン処理を記述しました。

main.go
package main

import (
    "./src/controller"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

    v1 := router.Group("/qiita/api/v1")
    {
        v1.GET("/user-info", controller.QiitaGET)
    }
    router.Run(":9000")
}

実行

❯ go run main.go
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /qiita/api/v1/user-info   --> _/Users/********/Desktop/Qiita_PoC_API/src/controller.QiitaGET (3 handlers)
[GIN-debug] Listening and serving HTTP on :9000

APIを叩く際には、postManを使用しました。
スクリーンショット 2020-10-12 23.22.24.png

参考

Qiita API

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

golandとDocker設定

golandを使う人への参考記事まとめです。

GolandでDockerを使う

Docker - 公式ヘルプ | GoLand
公式ページ。これだけでもいい人もいるはず。日本語が少し不自然。

GolandでDocker上のサーバーをRemote Debug - Qiita
リモートデバッグの解説が日本語で書かれていて読みやすい。

Docker上のGo製Webアプリケーションをリモートデバッグする - Qiita
実際に使用しているコードがわかります。

golandの設定

GoglandでオススメのGo快適開発環境構築方法 - Qiita
基本的なgolandの使い方、dockerはの解説はありません。

【Go言語】Airでホットリロードをする方法 | Awesome Blog
golandでホットリロードってなによ?ってときに読みましょう

DockerでGo言語の開発環境

DockerでGoの開発環境を構築する - Qiita
dockerのみでgolandの解説はありませんが、基本を振り返る時に最適

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AtCoder Regular Contest 105のメモ

前置き

Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。

問題

https://atcoder.jp/contests/arc105

A

Q_A.go
package main

import (
    "fmt"
)

func main() {
    var a,b,c,d int
    fmt.Scanf("%d %d %d %d", &a, &b, &c, &d)

    flag := false 

    flag = (a == b+c+d || a+b == c+d || a+c == b+d || a+d == b+c || a+b+c == d || a+b+d == c || a+c+d == b )

    var s string
    if flag == true{
        s = "Yes"
    }else{
        s = "No"
    }
    fmt.Printf("%s\n", s)
}

B

Q_B.go
package main

import (
  "fmt"
)

func main() {
  var N, a int
  fmt.Scan(&N)

  ans := 0
  for i := 0; i < N; i++ {
    fmt.Scan(&a)
    ans = gcd(ans ,a)
  }
  fmt.Printf("%d\n", ans)
}

func gcd(a, b int) int {
  if b == 0 {
    return a
  }
  return gcd(b, a % b)
}

C

覚えてたら後で書きます。

D

覚えてたら後で書きます。

E

覚えてたら後で書きます。

F

覚えてたら後で書きます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む