- 投稿日:2020-06-30T21:49:37+09:00
Goにおけるnewと宣言のみの違い
newで初期化することとvarで宣言する違い
newで初期化
newで初期化すると以下のようなコードになります。
var i *int = new(int)これを出力すると
package main import "fmt" func main() { var i *int = new(int) //もしくはi := new(int) fmt.Printf("%T %v\n", i, *i) → *int 0 }となってnewでは
ポインタ型
を返します。構造体だったりはポインタで使用されることが多いのでnewを使うことが多い。
type Vertex struct{ X,Y int } .... v := new(Vertex) //v := &Vertex{}と同じvarで宣言のみ
varで宣言すると以下のようなコードになります。
var i2 *intこれを出力すると
package main import "fmt" func main() { var i2 *int fmt.Printf("%T\n", i2) → *int fmt.Println(i2) → <nil> }となり、nil値となる。
javaなどと同じで宣言だけでは、入らないですね。
- 投稿日:2020-06-30T20:32:30+09:00
gin gormでテーブル操作(少し改良版)
以前gin gormでテーブル操作で一連のテーブル操作をやってみた
しかし、どうもBDのコネクションは保持したままの方が良いようなので、修正してみる
ついでにこちらと同じGo Modules管理に変更している以下雑にコードをのせているだけなので、何が変わったかは↑の記事と見比べてください(すまん
docker-compose.yml
docker-compose.ymlservices: app: container_name: gin_app image: golang:1.12.0-alpine volumes: - .:/go/src/app command: > sh -c "cd /go/src/app && apk update && apk add --no-cache git && GO111MODULE=off go get -u github.com/codegangsta/gin && go mod init || : && gin -i run" ports: - 3001:3001 environment: GO111MODULE: "on"DB
db/db.gopackage db import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) var database *gorm.DB func Connection() *gorm.DB { var err error database, err = gorm.Open("mysql", "root:@tcp(db:3306)/gin_app?charset=utf8&parseTime=True&loc=Local") if err != nil { panic("failed to connect database") } database.LogMode(true) return database } func DB() *gorm.DB { return database }毎回接続せずにコネクションを変数に保持する形式に変更。他packageでは
db.DB()
で取得できるようにしているマイグレーション
こちらもメソッドに。任意で実行できるように変更
migrate/migrate.gopackage main import ( "app/db" "app/model" _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() { db.Connection() defer db.DB().Close() db.DB().AutoMigrate(&model.User{}) db.DB().AutoMigrate(&model.UserName{}) }マイグレーション実行
Go Modules管理に変更したら以前の方法だとエラーになるので少し修正$ docker exec -it gin_app sh -c "cd /go/src/app; go run migrate/migrate.go"モデル
ここは変更なし
model/user.gopackage model import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type User struct { gorm.Model UserName UserName }model/user_name.gopackage model import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type UserName struct { gorm.Model UserID uint Name string }コントローラ
DBの取得方法を変更
controller/user.gopackage controller import ( "app/db" "app/model" "github.com/gin-gonic/gin" ) type User struct{} func NewUser() *User { return &User{} } func (t *User) Get(c *gin.Context) { db := db.DB() var user model.User result := db.First(&user, c.Param("id")).Related(&user.UserName) c.JSON(200, result.Value) } func (t *User) List(c *gin.Context) { db := db.DB() var users []model.User result := db.Preload("UserName").Find(&users) c.JSON(200, result.Value) } func (t *User) Create(c *gin.Context) { db := db.DB() var user model.User db.Create(&user) var userName model.UserName c.BindJSON(&userName) userName.UserID = user.ID db.Create(&userName) } func (t *User) Update(c *gin.Context) { db := db.DB() var user model.User db.First(&user, c.Param("id")).Related(&user.UserName) if user.UserName.ID > 0 { c.BindJSON(&user.UserName) db.Save(&user.UserName) } } func (t *User) Delete(c *gin.Context) { db := db.DB() var user model.User db.First(&user, c.Param("id")).Related(&user.UserName) if user.ID > 0 { db.Delete(&user) } if user.UserName.ID > 0 { db.Delete(&user.UserName) } // こっちの消し方でも良い // db.Where("id = ?", c.Param("id")).Delete(&model.User{}) // db.Where("user_id = ?", c.Param("id")).Delete(&model.UserName{}) }main
はじめにDB接続をするように変更
main.gopackage main import ( "app/controller" "github.com/gin-gonic/gin" _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() { db.Connection() defer db.DB().Close() r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.GET("/users", controller.NewUser().List) r.GET("/users/:id", controller.NewUser().Get) r.POST("/users", controller.NewUser().Create) r.PUT("/users/:id", controller.NewUser().Update) r.DELETE("/users/:id", controller.NewUser().Delete) r.Run() }
- 投稿日:2020-06-30T18:52:29+09:00
CircleCIからCloudRunへ自動的にデプロイする
この記事は、CircleCIを使って、Google Cloud Platform(GCP)のサービスであるCloudRunへシステムをデプロイをする方法をまとめたものです。
CircleCIを使えばgithubにpushしたソースコードを自動的にテスト、ビルド、デプロイすることができます。
なおこの記事内では、githubとCircleCIの連携方法やCircleCIの利用方法については省略しています。ポイント
・ CircleCIのCloudRun用Orbsを利用する
・ GCPに接続するための接続情報を環境変数に設定する構成
全体のイメージはこんな感じ。
GitHubの構成はこんな感じ。
言語はGo1.13です。github/.circleci |-config.yml /sample-app |-Dockerfile |-main.go |-... (他アプリソース群)手順
- CircleCIのジョブ設定 (設定ファイルを作成)
- CircleCIからContainerRegistry、ClourRunに接続するための環境変数を設定
- githubに対してソースコードをpushする
CircleCIのジョブ設定
CircleCIのジョブ設定は、上記のようにgithubのリポジトリにconfig.ymlを追加するだけです。
CircleCIからCloudRunにデプロイするためのOrbsが提供されているのでそれを利用します。
今回はマネージドのCloudRunの方にデプロイするようにします。ちなみにOrbsというのは、いわゆるライブラリのようなもので、他のymlファイルをインポートしています。
自分で書くのが難しい部分を使いやすくして提供してくれています。下記の設定は、githubにpushされたソースコードをテスト、ビルド、デプロイする設定になっています。
config.ymlversion: 2.1 # use CircleCI 2.1 orbs: gcp-cloud-run: circleci/gcp-cloud-run@1.0.2 executors: build: docker: - image: circleci/golang:1.13 # jobs: # テスト時はgo1.13のdockerイメージを使ってgo testを実行 test-job: executor: name: build steps: - checkout - run: name: Run unit tests command: | cd sample-app go test -v ./... # デプロイ時はContainerRegistoryにビルドしたイメージを保管し、CloudRunへのデプロイを実行 # リポジトリのDockerfileに従ってビルドされる # プロジェクトID test-project-hogehogeは変更する deploy-job: docker: - image: 'cimg/base:stable' steps: - checkout - run: command: cd sample-app - gcp-cloud-run/init - gcp-cloud-run/build: source: ./sample-app tag: 'asia.gcr.io/test-project-hogehoge/sample-app:${CIRCLE_SHA1}' - gcp-cloud-run/deploy: image: 'asia.gcr.io/test-project-hogehoge/sample-app:${CIRCLE_SHA1}' platform: managed region: asia-northeast1 service-name: sample-app unauthenticated: true #テスト用ジョブ(テストのみ)とデプロイ用ジョブ(ビルド、デプロイ)に分けて実行 workflows: test-and-deploy: jobs: - test-job - deploy-jobCircleCIの環境設定
CircleCIからGCPへ接続するためにはサービスアカウント情報が必要になります。
なのでアクセス権限を持ったサービスアカウント(のJSONキー)をGCP上で作成しておいてください。
※よくわからなければCloudBuildとCloudRunの管理者権限を付与すれば権限上は大丈夫CircleCIでは下記を環境変数として設定することでGCPへの接続が可能になります。
・GCLOUD_SERVICE_KEY
・GOOGLE_PROJECT_ID
・GOOGLE_COMPUTE_ZONEこれらを下記のようにCircleCIプロジェクト設定画面で設定すればOK
※GCLOUD_SERVICE_KEYにはJSONキーをそのまま入れています
CloudRunの設定
CloudRun側では特に設定は必要ありません。
CircleCIが完了すれば自動的にデプロイされます。CircleCIの実行
githubにソースコードをpushしてCircleCIを実行してみてください。
CircleCIでテストが実行され、ビルドしたコンテナイメージがCloudRunにデプロイするまでを自動的に実現することができます。参考
https://circleci.com/orbs/registry/orb/circleci/gcp-cloud-run
https://circleci.com/docs/ja/2.0/google-auth/
- 投稿日:2020-06-30T18:51:00+09:00
CloudRunでRedis(Memorystore)を利用する
この記事は、Google Cloud Platform(GCP)のサービスであるCloudRunでRedisを利用するための方法をまとめたものです。
CloudRundもサーバレスVPCアクセスが利用可能になったので、CloudRunからMemorystore(Redis)を利用することが可能になっています。
CluodRunでできることがどんどん増えていくのは嬉しいですね。ポイント
- フルマネージドなインメモリサービスであるMemorystore(Redis,Memcached)を利用する
- Memorystoreを利用するにはプライベートアドレスでの接続が必要
- GAEやCloudRunから接続する場合はサーバーレスVPCアクセスを利用する
※GAEやCloudRunはマネージドサービスなのでプライベートアドレスが付与されない手順
- サーバーレスVPCを作成
- MemoryStoreを作成
- CloudRunを作成
1. サーバーレスVPCを作成
CloudRunからアクセスするためのネットワークを作成します。
GCPコンソールから
VPCネットワーク > サーバーレスVPCアクセス
に移動し、コネクタを作成
(初回はAPIを有効化する必要あり)例えば下記のように設定します。
2. Memorystore(Redis)を作成
次に、Memorystore(Redis)を下記の点に注意して作成します。
ロケーションを 1.で作成したコネクタと同じリージョンにする
(今回はasia-northeast1)ネットワークを1.で作成したコネクタと同じネットワークにする
(今回はdefault)これらを設定することで 1.のコネクタを通したVPCアクセスが可能になります。
3. CloudRunを作成
最後に、CloudRunにソースコードをデプロイします。
変数設定にRedisのIPアドレス、ポート番号を指定する
2.で作成したMemorystoreのIPアドレス、ポート番号を環境変数に下記のように設定します。
接続設定に作成したサーバーレスVPCコネクタを指定する
CloudRunが接続するコネクタを下記の画像のように設定します。
サンプルコード
サイト訪問によるカウントアップ
main.go// Command redis is a basic app that connects to a managed Redis instance. package main import ( "fmt" "log" "net/http" "os" "github.com/gomodule/redigo/redis" ) var redisPool *redis.Pool func incrementHandler(w http.ResponseWriter, r *http.Request) { conn := redisPool.Get() defer conn.Close() counter, err := redis.Int(conn.Do("INCR", "visits")) if err != nil { http.Error(w, "Error incrementing visitor counter", http.StatusInternalServerError) return } fmt.Fprintf(w, "Visitor number: %d", counter) } func main() { redisHost := os.Getenv("REDISHOST") redisPort := os.Getenv("REDISPORT") redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort) const maxConnections = 10 redisPool = redis.NewPool(func() (redis.Conn, error) { return redis.Dial("tcp", redisAddr) }, maxConnections) http.HandleFunc("/", incrementHandler) port := os.Getenv("PORT") if port == "" { port = "8080" } log.Printf("Listening on port %s", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatal(err) } }Dockerfileはかなり適当...
FROM golang:1.13 RUN mkdir -p /app WORKDIR /app COPY . /app RUN go build /app/main.go ENTRYPOINT ["/app/main"]ここまでの設定ができていれば、リロードするごとに数値がカウントアップされるサイトがデプロイされていると思います。
参考サイト
GAEからサーバレスVPCへの接続
https://cloud.google.com/appengine/docs/standard/python/connecting-vpc?hl=ja#creating_a_connectorGAE/GoでRedisへ接続する
https://cloud.google.com/appengine/docs/standard/go/using-memorystore?hl=ja
- 投稿日:2020-06-30T17:23:45+09:00
Rust は流行りそうもないので、Go を使う。
最近、暇で以下のサービスを作った。
https://deau-project.herokuapp.com/バックエンドには仕事で使ったことがない、Go にした。
勉強してたのは、Rust で、仕事のCSVを分析するシステムを Rust で作ったけど、
この先、使うことがないのでは? と思っている。以前、Haskell が流行りそうで、だいぶ勉強したけど、今では話題にすらならない。
関数型も、いまいち浸透していない。流行る言語は、何かしらの手間を無くす。
Ruby が流行ったのは、Rails がフレームワーク使用時の共通作業を無くしたから。
PHP が未だに廃れないのは、WordPress が共通作業を無くしてるから。Go は流行る。もう流行っている?
理由は学習コストを減らしたから。今回、Go Gin を使用した、そして、簡単に実装できた。
情報も充分にあった。Rust でも、情報に関しては充分にある。
ただ、実装時に面倒だなと感じることが多い。
私のように趣味で実装するなら、尚更、面倒に感じる。Rust が流行るには、組込み系にターゲットを絞るか、
当時の Rails のような手間を省く何かが必要だと思う。
組込み系で考えれば、C++でよくあるミスを防げる。確認の手間を省ける。今回、サーバーサイドに Go を使用したが、この先はどうかわからない。
趣味でならいいが、仕事で使うとなると、関数型である必要がある。
もし、今から新しいシステムを作るとして、サーバーサイドに何を使用すればいいのか。
- 投稿日:2020-06-30T14:53:39+09:00
Goの実行環境をDockerで構築しようと際に発生した「no Go files in /go/src/github.com/go-playground/localesエラー」を解決
はじめに
root@xxxxxxxxxxxx:/go# go get github.com/go-playground/localesいつものようにパッケージをインストールしていたら次のエラーが発生。
can't load package: package github.com/go-playground/locales: no Go files in /go/src/github.com/go-playground/localesここのlocalesフォルダの中に何もファイルなんてねーよ!って言われてるんですね。そんなこと言われても。。。
解決方法
go getをしても同じエラーが吐かれるだけだったので、試しにlocalesフォルダを削除して、再度以下コマンドを叩いてみました。
root@xxxxxxxxxxxx:/go# go get github.com/go-playground/localesすると2分程度でパッケージのインストールが終わりました。
入った!
無事コンパイルが終了し、GoをDocker環境で構築することができました。Docker便利です。
- 投稿日:2020-06-30T14:35:51+09:00
MacにGo言語開発環境をインストールする
最終更新日
2020年6月30日
検証を行ったmacOSのバージョンは下記です。
- macOS Catalina 10.15.5
インストールするもののバージョンは下記です。
- Go SDK 1.14.4
- Visual Studio CodeのGo Extension(Visual Studio Code自体のインストールは別記事にて → MacにVisual Studio Code(VSCode)をインストールする)
- Git(別記事にて → MacにGitをインストールする)
この記事が古くなった場合、下記の手順は最新のインストール手順とは異なっている可能性があります。
Go SDK
インストール
(1) https://golang.org/dl/ にアクセスしてください。
(2) go1.14.4.darwin-amd64.pkg をダウンロードしてください。
(3) ダウンロードしたPKGファイルをダブルクリックしてください。
(4) [続ける]をクリックしてください。
(5) [このコンピュータのすべてのユーザ用にインストール]を選択して、[続ける]をクリックしてください。
(6) [インストール]をクリックしてください。パスワード入力を求められたら、macOSアカウントのパスワードを入力してください。
(7) [閉じる]をクリックしてください。
(8) [ゴミ箱に入れる]をクリックしてください。
確認
(1) ターミナルで
go version
コマンドを実行してください。インストールしたGoのバージョンが表示されれば成功です。Visual Studio CodeのGo Extension
Visual Studio Code自体のインストールは別記事にて → MacにVisual Studio Code(VSCode)をインストールする
インストール
(1) Visual Studio Codeを起動してください。
(2) Extensionの検索画面を開いて「go」で検索→[Go Team at Google]のGoエクステンションをInstallしてください。
動作確認
(1) 適当なフォルダにhello.goというファイルを作成して、Visual Studio Codeで下記のように編集してください。
package main import "fmt" func main() { fmt.Println("Hello!"); }(2) ターミナルで先ほどのフォルダに移動して、
go run hello.go
コマンドを実行してください。「Hello!」と表示されれば成功です。Git
Gitのインストール
別記事にて → MacにGitをインストールする
動作確認
(1) 適当なフォルダ(先ほどのhello.goのフォルダとは別にしてください)に、go.modというファイルを作成して、Visual Studio Codeで下記のように編集してください。
module sample go 1.14(2) ターミナルで先ほどのフォルダに移動して、
go get github.com/labstack/echo/v4@v4.1.16
コマンドを実行してください。下記のように表示されれば成功です。(3) go.modを確認してください。
require github.com/labstack/echo/v4 v4.1.16 // indirect
という記述が追加されています。module sample go 1.14 require github.com/labstack/echo/v4 v4.1.16 // indirect(4) go.modと同じフォルダにserver.goというファイルを作成して、Visual Studio Codeで下記のように編集してください。
package main import ( "net/http" "github.com/labstack/echo/v4" ) func main() { e := echo.New() e.GET("/", hello) e.Logger.Fatal(e.Start(":1323")) } func hello(c echo.Context) error { return c.String(http.StatusOK, "Hello!") }(5) ターミナルで先ほどのフォルダに移動して、
go run server.go
コマンドを実行してください。次のように表示されれば成功です。(6) ブラウザで http://localhost:1323 にアクセスしてください。「Hello!」と表示されれば成功です。
(7) 先ほどのターミナルでCtrl + Cを押下してください。Echoが停止します。
- 投稿日:2020-06-30T13:39:51+09:00
WindowsにGo言語開発環境をインストールする
最終更新日
2020年6月30日
検証を行ったWindows 10のバージョンは下記です。
- Windows 10 Home 2004 19041.329インストールするもののバージョンは下記です。
- Go SDK 1.14.4
- Visual Studio CodeのGo Extension(Visual Studio Code自体のインストールは別記事にて → WindowsにVisual Studio Codeをインストールする)
- Git(別記事にて → WindowsにGit Bashをインストールする)この記事が古くなった場合、下記の手順は最新のインストール手順とは異なっている可能性があります。
Go SDK
インストール
(1) https://golang.org/dl/ にアクセスしてください。
(2) go1.14.4.windows-amd64.msi をダウンロードしてください。
(3) ダウンロードしたMSIファイルをダブルクリックしてください。
(4) [Next]をクリックしてください。
(5) [I accept the terms in the License Agreement]にチェックを入れて、[Next]をクリックしてください。
(6) [Next]をクリックしてください。
(7) [Install]をクリックしてください。
(8) [はい]をクリックしてください。
確認
(1) コマンドプロンプトで
go version
コマンドを実行してください。インストールしたGoのバージョンが表示されれば成功です。Visual Studio CodeのGo Extension
Visual Studio Code自体のインストールは別記事にて → WindowsにVisual Studio Codeをインストールする
インストール
(1) Visual Studio Codeを起動してください。
(2) Extensionの検索画面を開いて「go」で検索→[Go Team at Google]のGoエクステンションをInstallしてください。
動作確認
(1) 適当なフォルダにhello.goというファイルを作成して、Visual Studio Codeで下記のように編集してください。
package main import "fmt" func main() { fmt.Println("Hello!"); }(2) コマンドプロンプトで先ほどのフォルダに移動して、
go run hello.go
コマンドを実行してください。「Hello!」と表示されれば成功です。Git
Gitのインストール
別記事にて → WindowsにGit Bashをインストールする
動作確認
(1) 適当なフォルダ(先ほどのhello.goのフォルダとは別にしてください)に、go.modというファイルを作成して、Visual Studio Codeで下記のように編集してください。
module sample go 1.14(2) コマンドプロンプトで先ほどのフォルダに移動して、
go get github.com/labstack/echo/v4@v4.1.16
コマンドを実行してください。下記のように表示されれば成功です。(3) go.modを確認してください。
require github.com/labstack/echo/v4 v4.1.16 // indirect
という記述が追加されています。module sample go 1.14 require github.com/labstack/echo/v4 v4.1.16 // indirect(4) go.modと同じフォルダにserver.goというファイルを作成して、Visual Studio Codeで下記のように編集してください。
package main import ( "net/http" "github.com/labstack/echo/v4" ) func main() { e := echo.New() e.GET("/", hello) e.Logger.Fatal(e.Start(":1323")) } func hello(c echo.Context) error { return c.String(http.StatusOK, "Hello!") }(5) コマンドプロンプトで先ほどのフォルダに移動して、
go run server.go
コマンドを実行してください。次のようなダイアログが表示された場合は[アクセスを許可する]をクリックしてください。
次のように表示されれば成功です。
(6) ブラウザで http://localhost:1323 にアクセスしてください。「Hello!」と表示されれば成功です。
(7) 先ほどのコマンドプロンプトでCtrl + Cを押下してください。Echoが停止します。
- 投稿日:2020-06-30T09:57:10+09:00
Ionic & golangでリアルタイム大喜利アプリを作りました
アプリのリリースまでなんとか漕ぎ着けたので、宣伝も兼ねて使ったフレームワークについて紹介します。
どんなアプリか
写真で一言アプリです。
特徴的なのはリアルタイムで集まった人たちが、お互いに投稿し合ったボケを評価し合う部分です。マッチングした最大10名が、制限時間内に一つのお題写真に対してボケを投稿します。
投稿はお互いに評価することができ、一定数イイネを集めると一本獲得になります。こちらからダウンロード可能です。
よかったら遊んでみてください。android
https://play.google.com/store/apps/details?id=jp.co.popbits.funnyappios
https://apps.apple.com/jp/app/funny-one/id1515018792アプリ側
ionic
アプリのベースはIonic Frameworkで作成しました。
ざっくりいうと、
webview + Angular
にネイティブっぽいリッチな見た目のコンポーネントと、共通化されたプラグインが利用できます。
プラグインの例としてはSocial Sharingやdeeplink等があります。Angularではなく、vueやreactで記載することも可能なようです。
※reactは最近入ったらしい。
android, ios同一のコードで記載できるので工数削減になりました。
環境構築やビルドなどもかなりスムーズにできました。
(多少のつまづきはありますが、ネイティブアプリの環境構築にはつきものです)懸念点として、webviewベースであるためパフォーマンスがあまり良くないのではないか気になりましたが、
端末の性能も上がってきているからか、思ったよりサクサク動いてくれています。createjs
大喜利バトルの部分はcreatejsで作成しました。
https://createjs.com/Adobe Animate
https://www.adobe.com/jp/products/animate.html
でcreatejs用にアニメーションを書き出しています。アプリへのつなぎ込みには色々と試行錯誤が必要でしたが、細かい話になるので割愛します。
大喜利バトルでは後述するgolangサーバとwebsocketで接続し、イベント毎にアニメーションを変化させます。
サーバ側
golang
リアルタイムや並列処理に強そうなので採用しました。
pythonもよく書くのですが、golangは型があるのでバグが起きづらい、
パフォーマンスが良いなどのメリットがあります。コードは誰が書いても同じ書き方になるよう矯正され、必然的に可読性が高くなります。
一方、リアルタイム部分(websoket接続)はgoroutine と channelを駆使して作るのですが、
正直自分以外理解できないコードになってしまったと思います。並列処理そのものが難しいのもあると思います。
通常の処理とは違いコードの上から追っていくだけでは読み解くことができず、
どこからchannnelにアクセスが有るなど把握していないといけません。並列処理は色々な書き方ができるので正解がない感じです。
gin
https://github.com/gin-gonic/gin
デファクトスタンダードっぽいので採用しました。
良さげです。melody
https://github.com/olahol/melody
websocketを扱う際にいい感じの機能を提供してくれます。
sqlx + squirrel
https://github.com/jmoiron/sqlx
クエリ結果をstructsにマッピングしてくれます。https://github.com/Masterminds/squirrel
SQLクエリビルダーです。
where句の検索条件をqueryオブジェクトに対して注入していく、
みたいなことがやりたい場合はこれでSQLを作ります。最初はgormを使っていたのですが、最終的に上の構成に書き換えることにしました。
gormは人気があるようなので使っていたのですが、挙動が直感的でなかったのと、
思いも寄らない部分で大量のSQLを発行されていたことがあったりで、嫌になってやめました。まとめ
色々紹介しましたが、ionicはかなり気軽にアプリが作成できるので本当におすすめです。
- 投稿日:2020-06-30T08:54:41+09:00
go修行14日目 ユニットテストとか
testing
└── mylib ├── human.go ├── math.go ├── math_test.gotestされるファイル
package mylib func Average(s []int) int { total := 0 for _, i := range s { total += i } return int(total / len(s)) }testするファイル
3
が期待されるpackage mylib import "testing" func TestAverage(t *testing.T) { v := Average([]int{1, 2, 3, 4, 5}) if v != 3 { t.Error("Expected 3, got", v) } }run test
- vscodeから
- コマンドラインから
PS C:\Users\yuta\go\src\awesomeProject> go test ./... ? awesomeProject [no test files] ok awesomeProject/mylib (cached) ? awesomeProject/mylib/under [no test files]
- 数字変えるとFAILになる
package mylib import "testing" func TestAverage(t *testing.T) { v := Average([]int{1, 2, 3, 4, 5, 6,7}) if v != 3 { t.Error("Expected 3, got", v) } }--- FAIL: TestAverage (0.00s) C:\Users\yuta\go\src\awesomeProject\mylib\math_test.go:8: Expected 3, got 4 FAIL FAIL awesomeProject/mylib 0.374s FAIL
- Skip処理
package mylib import "testing" var Debug bool = true func TestAverage(t *testing.T) { // Debugがtrueならスキップ if Debug { t.Skip("Skip reason") } v := Average([]int{1, 2, 3, 4, 5, 6, 7}) if v != 3 { t.Error("Expected 3, got", v) } }PS C:\Users\yuta\go\src\awesomeProject> go test ./... -v ? awesomeProject [no test files] === RUN TestAverage TestAverage: math_test.go:10: Skip reason --- SKIP: TestAverage (0.00s) PASS ok awesomeProject/mylib 0.368s ? awesomeProject/mylib/under [no test files]