如果您要开始使用Go语言,这是一些您可能要注意的规范
本文是2021年的Qiita上Go语言的日历活动中的第三个日历的第三天。
这是什么?
-
- あくまで筆者の主観で、Golangを使ったアプリケーションはこういった書き方が多い/こういう風にすると良さそう、を書き連ねる記事
「主観で」とはいえど、なるべく有名どころのライブラリなどを参考に持ち出して執筆します
Golangの基本文法が分かる人向け
缩进以制表符为主流
-
- Golangのデフォルトがタブ
標準ライブラリやPlayground、有名なライブラリなどを見るとタブ採用が多い
参考: timeパッケージのSleepメソッド
参考: Go Playground
参考: webフレームワークのecho
タブだとGitHub上でコード読みにくい!な問題への対処法
.editorconfigファイルを使うことで、見た目上のインデント幅を任意のサイズに指定できる
参考: pre { tab-size: 4 } · Issue #170 · isaacs/github
参考: echoにも指定されている
または、Chrome拡張機能もある
GitHub Custom Tab Size – Chrome ウェブストア
// Before
func main() {
fmt.Println("スペース4つ")
}
// After
func main() {
fmt.Println("タブ")
}
在编辑器上,可以区分空格和制表符的区别,但在 Qiita 的文章显示中,无法传达这个差别。
测试在同一层级上是可以的。
-
- ここでいう「階層」とは「package」を指す
-
- 階層を分けてしまうとunexported(private)な構造体や変数を単体テストで使うためにはexport(public)が必要になる
実処理としてはexport不要だが、テストのためだけにexportする、のような状況が生じてしまうので良くない
これを避けるために同階層に置くべし
下記参考を見るとそうなっている
参考: webフレームワークのecho
参考: csvライブラリのgocsv
ただし、基本的には同階層に置いているがtestspackageを切ってその中にもテストファイル置くパターンもある(理由はしっかり中身読めばわかる…はず…)
ORMのgorm
// Before
┣ repository
┣ campaign_repository.go
┣ repository_test
┣ campaign_repository_test.go
// After
┣ repository
┣ campaign_repository.go
┣ campaign_repository_test.go
错误信息基本上要以小写字母开头,避免使用句点作为结尾。
-
- エラーメッセージ(標準だとfmt.Errorf, errors.New)に関しては、「小文字始まり」「句読点終わりにしない」、が公式の推奨
エラーメッセージは別のエラーメッセージやログメッセージなどの中で使われることもあるので、エラーメッセージを文章のようにしてしまうと読みにくくなるため
もちろん、固有名詞や頭字語はこの限りではない
参考: CodeReviewComments · golang/go Wiki
ログメッセージに関してはこの限りではないが、揃えたほうがわかりやすいため、基本的に「小文字始まり」「句読点終わりにしない」で良さそう
こちらは諸説ありそう
// Before
err := errors.New("Required field cannot be null.")
log.Errorf("Create test file failed. (err=%+v)", err)
// After
err := errors.New("required field cannot be null")
log.Errorf("create test file failed(err=%+v)", err)
写错误相关的方式
-
- こちらもCodeReviewCommentsを参考にした話
参考: CodeReviewComments · golang/go Wiki
エラーは即時リターン
// Before
err := db.Err
if err != nil {
// エラーハンドリング
} else {
// 通常処理
}
// After
err := db.Err
if err != nil {
// エラーハンドリング
}
// 通常処理
err変数のスコープは狭くできる
スコープ狭くなってヨシ
// Before
err := db.Err
if err != nil {
return err
}
// After
if err := db.Err; err != nil {
return err
}
- ただ、スコープを無理に狭くしすぎると逆に読みにくくなるので注意
// Before
if x, err := f(); err != nil {
return err
} else {
// use x
}
// After
x, err := f()
if err != nil {
return err
}
// use x
变量名
-
- Golangでは略語は全部小文字 or 大文字に
ID, id→Identifierの略語
CV, cv→Conversionの略語
参考: CodeReviewComments · golang/go Wiki
// Before
var campaignId int64
var CvData struct{}
// After
var campaignID int64
var CVData struct{}
每句话中的顺序是 import, type, const, var
-
- 標準パッケージ参考にするとimport→type→const→var→funcの順になっている
参考: zoneinfo.go – Go
package time
import (
"toto"
...
)
type Titi struct {
name string
...
}
const (
tata = ""
...
)
var (
tutu = ""
...
)
导入语句内部的说明顺序
-
- 標準パッケージの塊を先頭に、あとは他の塊ごとに空行を挟んで記述し、それぞれの塊の中ではアルファベット順で記述
参考: CodeReviewComments · golang/go Wiki
// Before
import (
"os"
"fmt"
"github.com/toto/titi"
"github.com/tata/tutu"
"log"
"myapp/foo"
"myapp/user"
"net/http"
)
// After
import (
"fmt"
"log"
"net/http"
"os"
"myapp/foo"
"myapp/user"
"github.com/tata/tutu"
"github.com/toto/titi"
)
把常数归类
-
- constは複数ある場合はまとめる
同カテゴリである場合はまとめて、同カテゴリではない場合は別でまとめる
変数varについても同様
// Before
const expireDate = "2006-01-02T15:04:05"
const maxLength = 100
const MethodGet = "GET"
const MethodPost = "POST"
// After
const (
expireDate = "2006-01-02T15:04:05"
maxLength = 100
)
const (
MethodGet = "GET"
MethodPost = "POST"
)
选择-执行语句块
-
- これは基本文法だけど、別の条件で同じ処理の書き方忘れがちなので載せる
ちなみに、Golangではcaseごとでbreakするのでfallthroughしたい場合はcase文の最後にfallthroughを明記する
// Before
switch type {
case enum.ONE:
fmt.Println("hoge")
case enum.TWO:
fmt.Println("hoge")
case enum.THREE:
fmt.Println("fuga")
default:
fmt.Println("piyo")
}
// After
switch type {
case enum.ONE, enum.TWO:
fmt.Println("hoge")
case enum.THREE:
fmt.Println("fuga")
default:
fmt.Println("piyo")
}
我想要一起阅读
CodeReviewComments · golang/go Wiki
本記事でもかなり参考にしているので原文を是非
Go言語の記述の迷いどころについて
この記事書いた後に見つけた
「Go言語らしさ」とは何か? Simplicityの哲学を理解し、Go Wayに沿った開発を進めることの良さ – エンジニアHub|Webエンジニアのキャリアを考える!
Golang書くならこの辺も読みたいかも