Go コーディング標準のセットを共有してください。収集へようこそ!
最近、プロジェクト内の多くの Go 言語コードをコードレビューしたので、メモの記録としてコードの仕様をまとめる必要があります。
前述したように、これは私たちのチームの単なる規範です。
今日は Go のコーディング標準について説明します。これは、パッケージ インジェクション/変数/定数の命名、基本構文、関数、エラー処理、エクスペリエンスなど、いくつかの主要なモジュールに大別されます。 [推奨: golang チュートリアル ]
1. コード スタイル
1.1 コード形式
- コードは gofmt でフォーマットする必要があります。設定は自分で検索できます。
- 記述するコードの各行は 120 文字を超えてはならず、超過部分は改行で解決する必要があります。
- 1 つのファイルの最大行数は 800 行を超えません。
- 1 つの関数の最大行数は 80 行を超えません。
- インポート仕様
- パッケージの導入に相対パスを使用しないでください。たとえば、
import ../util/net
- パッケージをインポートする場合、複数の同一のパスが必要です。パッケージ 名前の競合がある場合は、インポートされたエイリアス
- パッケージの導入に相対パスを使用しないでください。たとえば、
// bad "github.com/google/uuid" // good uuid "github.com/google/uuid"
- を使用する必要があります。インポートされたパッケージはグループ化することをお勧めします。匿名パッケージを参照する場合は、便宜上、新しいグループを使用し、コメントを追加することをお勧めします。パートナーの読書
import ( // Go 标准库 "fmt" //第三方包 "github.com/jinzhu/gorm" "github.com/google/uuid" "github.com/go-redis/redis/v8" // 匿名包 /import mysql driver _"github.com/jinzhu/gorm/dialects/mysql" // 内部包 slice "xxx.local/pkg/v1/goslice" meta "xxx.local/pkg/v1/meta" gomap "xxx.local/pkg/v2/gomap")
1.2 宣言、初期化、定義
- 関数で複数の変数を使用する必要がある場合、関数の先頭で var 宣言を使用できます。関数の外で宣言された変数は := を使用できないため、落とし穴につながる可能性があります。わからない場合は、コメント エリアにメッセージを残してください (コメントするのは簡単ではありません)。
var ( port = 8081 metricServerPort = 2001)
- 構造体の初期化時に new(struct) の代わりに &struct を使用して、構造体の初期化との一貫性を確保し、構造体の初期化時に行を折り返します。
// bad stu := new(S) stu.Name = "张三" // good stu := &S{ Name:"李四" }
- make を使用して、マップや配列などを宣言するときにコンテナの容量を指定して、コンテンツを事前に割り当てる必要があります。
users := make(map[int]string, 10)tags := make([]int, 0, 10)
- 標準の var キーワードを使用し、式の型と異なる場合を除き、型を指定しないでください。
// bad var _f string F() func F() string { return "hello world!" } // good var _f F() func F() string { return "hello world!" }
1.3 エラー処理
- 関数がエラーを返した場合、エラーを処理する必要があります。ビジネスで許可されている場合は、_ を使用してエラーを受け入れ、無視できます。対応する遅延は、明示的な処理を行わずに処理できます。
// bad func InitConfig() error { ... } InitConfig() // good func InitConfig() error { ... } err := InitConfig() if err != nil { ... } // or _ := InitConfig()
- error を戻り値として使用する場合は、最後のパラメータとして返す必要があります
// bad func InitConfig() (error,int) { ... } // good func InitConfig() (int, error) { ... }
- エラーは個別に処理する必要があり、エラーが発生しないようにする必要があります。他のロジックと結合することもできます。
// bad res, err := InitConfig() if err != nil || res != nil { return err } // good res, err := InitConfig() if err != nil { return err } if res != nil { return fmt.Errorf("invalid result") }
1.4 パニック処理
- ビジネス コードでパニック エラーをスローすることは禁止されています。
- panic は、構成の読み取り、リンク ストレージ (redis、mysql など) などのサービスの開始前にのみ表示できます。
- ビジネス コードではパニックではなくエラーを使用することをお勧めします。
1.5 単体テスト
- 重要な関数ごとにテスト ケースを作成し、コードをマージするときにすべてのテストを自動的に実行する必要があります。
- ファイルの名前は xxx_test.go です。
- 関数の名前付けには、テスト関数名を使用することをお勧めします。
2. 命名規則
どの言語においても、命名規則はコード仕様において非常に重要であり、統一された正確な命名はコードの読みやすさを向上させるだけでなく、このコードは、この仲間が本当にそのやり方を知っていると人々に思わせることもできます。牛!
2.1 包命名规范
- 包名必须与目录名一致(这和其他 php、Java 还是有一点不太一样的),尽量采取有意义、简短的包名,不要与 go 的标准库名称一样。
- 包名小写,没有下划线,可以使用中划线隔开,使用多级目录来划分目录。
- 包名不要出现复数命名。
- 包名命名尽量简单一目了然,ge:user、log。
2.2 文件命名规范
- 文件名要见名思义,尽量简而短
- 文件名小写,组合词用下划线分割
2.3 函数命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 单元测试的函数用大驼峰,TestFunc。
2.4 结构体命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 避免使用 info 、data 这种无意义的名称。
- 命名使用名词而非动词。
- 结构体在声明和初始化的时候需要换行,eg:
type Student struct{ Name string Age uint8}student := Student{ Name: "张三", Age: 18,}
2.5 变量命名规范
- 和 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若变量为私有时,可以使用小写命名。
- 局部变量可以简写,eg:i 表示 index。
- 若变量代表 bool 值,则可以使用 Is 、Can、Has 前缀命名,eg:
var isExit boolvar canReturn bool
2.6 常量命名规范
- 必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若代表枚举值,需要先创建。
type Code intconst ( ErrNotFound Code = iota ErrFatal)
3. 类型
3.1 字符串
好像学过的语言中,都是从字符串开始说起的。就像写代码第一行都是从 Hello World!一样!同意的点赞哈。
- 字符串判空值
// bad if s == "" { ...} // good if len(s) == 0 { ...}
- 字符串去除前后子串。
// bad var s1 "hello world"var s2 "hello"var s3 strings.TrimPrefix(s1, s2) // good var s1 "hello world"var s2 "hello"var s3 stringif strings.HasPrefix(s1, s2){ s3 = s1[len(s2):]}
3.2 切片 slice
- 声明 slice。
// bad s := []string{}s := make([]string, 10) // good var s []string s := make([]string, 0, 10)
- 非空判断。
//bad if len(slice) >0 { ...} // good if slice != nil && len(slice) > 0 { ...}
- slice copy。
// badvar b1,b2 []bytefor i, v := range b1 { b2[i] = v}for i := range b1 { b2[i] = b1[i]}// goodcopy(b2,b1)
- slice 新增。
// bad var a,b []intfor _, v := range a { b = append(b,v)} // good var a, b []int b := append(b, a...)
3.4 结构体 struct
- 初始化需要多行。
type Student struct{ Name string Age uint8}student := Student{ Name: "张三", Age: 18,}
4. 控制语句
4.1 if
- if 可以用局部变量的方式初始化。
if err := InitConfig; err != nil { return err}
4.2 for
- 不允许在 for 中使用 defer, defer 只在函数结束时才会执行。
// bad for file := range files { fd, err := os.Open(file) if err != nil { return err } defer fd.close()} // good for file := range files{ func() { fd,err := os.open(file) if err!=nil { return err } defer fd.close() }()}
4.3 range
- 如果不需要 key 直接用 _ 忽略,value 也一样。
for _, v := range students { ...}for i, _ := range students { ...}for i, v := range students { ...}
注: 若操作指针时请注意不能直接用 s := v。想知道可以评论区告诉我哦!
4.4 switch
- 和其他语言不一样,必须要有 defalt
switch type { case 1: fmt.Println("type = 1") break case 2: fmt.Println("type = 2") break default : fmt.Println("unKnown type")}
4.5 goto
- 业务中不允许使用 goto。
- 框架和公共工具也不允许使用 goto。
5. 函数
- 传参和返回的变量小写字母。
- 传入参数时slice、map、interface、chan 禁止传递指针类型。
- 采用值传递,不用指针传值。
- 入参个数不能超出 5 个,超过的可以用 struct 传值。
5.1 函数参数
- 返回值超出 1 个时,需要用变量名返回。
- 多个返回值可以用 struct 传。
5.2 defer
- 当操作资源、或者事物需要提交回滚时,可以在创建开始下方就使用 defer 释放资源。
- 创建资源后判断 error,非 error 情况后在用 defer 释放。
5.3 代码嵌套
- 为了代码可读性,为了世界和平,尽量别用太多的嵌套,因为真的很难有人类能看懂。
6. 日常使用感悟
- 能不用全局变量就不用,可以用参数传值的方式,这样可以大大降低耦合,更有利于单元测试。
- 衣服开发中,在函数间多用 context 传递上下文,在请求开始时可以生成一个 request_id,便于链路、日志追踪。
6.1 提高性能
- 在业务开发中,尽量使用 strconv 来替代 fmt。
- 我们在使用 string 字符串类型时,当修改的场景较多,尽量在使用时用 []byte 来替代。因为每次对 string 的修改都需要重新在申请内存。
6.2 避免踩坑
- append 要小心自动扩容的情况,最好在申明时分配好容量,避免扩容所带来的性能上的损耗以及分配新的内存地址。若不能确定容量,应选择一个比较大一点的值。
- 并发场景下,map 非线程安全,需要加锁。还有一种评论区告诉我吧。
- interface 在编译期间无法被检查,使用上会出现 panic,需要注意
7. 总结
本篇很讲了 Go 语言的编码规范,当时想说的,规范是大家预定的东西,每个公司、团队都会有不一样的规范,只要大家一起遵循就好啦。你可以根据自己团队的需求,定一套属于自己团队的项目规范。如果想小伙伴一起遵循,可以借助一些工具来保障执行度。
讲了很多,虽然很基础,希望对于刚刚转 Go 语言,或者刚学习 Go 语言的同学有帮助吧。今天就到这里了。希望得到大家的一键三连。感谢!
本文系转载,原文链接:mp.weixin.qq.com/s/lfjP9DEia2WL4Ua...
以上がGo コーディング標準のセットを共有してください。収集へようこそ!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Go ではファイルを安全に読み書きすることが重要です。ガイドラインには以下が含まれます。 ファイル権限の確認 遅延を使用してファイルを閉じる ファイル パスの検証 コンテキスト タイムアウトの使用 これらのガイドラインに従うことで、データのセキュリティとアプリケーションの堅牢性が確保されます。

Go データベース接続の接続プーリングを構成するにはどうすればよいですか?データベース接続を作成するには、database/sql パッケージの DB タイプを使用します。同時接続の最大数を制御するには、MaxOpenConns を設定します。アイドル状態の接続の最大数を設定するには、ConnMaxLifetime を設定します。

Go フレームワークは、その高いパフォーマンスと同時実行性の利点で際立っていますが、比較的新しい、開発者エコシステムが小さい、一部の機能が欠けているなどの欠点もあります。さらに、急速な変化と学習曲線はフレームワークごとに異なる場合があります。 Gin フレームワークは、効率的なルーティング、組み込みの JSON サポート、強力なエラー処理機能により、RESTful API を構築するための一般的な選択肢です。

GoLang フレームワークと Go フレームワークの違いは、内部アーキテクチャと外部機能に反映されています。 GoLang フレームワークは Go 標準ライブラリに基づいてその機能を拡張していますが、Go フレームワークは特定の目的を達成するための独立したライブラリで構成されています。 GoLang フレームワークはより柔軟であり、Go フレームワークは使いやすいです。 GoLang フレームワークはパフォーマンスの点でわずかに優れており、Go フレームワークはよりスケーラブルです。ケース: gin-gonic (Go フレームワーク) は REST API の構築に使用され、Echo (GoLang フレームワーク) は Web アプリケーションの構築に使用されます。

ベスト プラクティス: 明確に定義されたエラー タイプ (エラー パッケージ) を使用してカスタム エラーを作成する 詳細を提供する エラーを適切にログに記録する エラーを正しく伝播し、非表示または抑制しないようにする コンテキストを追加するために必要に応じてエラーをラップする

JSON データは、gjson ライブラリまたは json.Unmarshal 関数を使用して MySQL データベースに保存できます。 gjson ライブラリは、JSON フィールドを解析するための便利なメソッドを提供します。json.Unmarshal 関数には、JSON データをアンマーシャリングするためのターゲット型ポインターが必要です。どちらの方法でも、SQL ステートメントを準備し、データをデータベースに永続化するために挿入操作を実行する必要があります。

Go フレームワークで一般的なセキュリティ問題に対処する方法 Web 開発で Go フレームワークが広く採用されているため、そのセキュリティを確保することが重要です。以下は、一般的なセキュリティ問題を解決するための実践的なガイドであり、サンプル コードも含まれています。 1. SQL インジェクション SQL インジェクション攻撃を防ぐには、プリペアド ステートメントまたはパラメータ化されたクエリを使用します。例: constquery="SELECT*FROMusersWHEREusername=?"stmt,err:=db.Prepare(query)iferr!=nil{//Handleerror}err=stmt.QueryR

FindStringSubmatch 関数は、正規表現に一致する最初の部分文字列を検索します。この関数は、最初の要素が一致した文字列全体で、後続の要素が個々の部分文字列である、一致する部分文字列を含むスライスを返します。コード例: regexp.FindStringSubmatch(text,pattern) は、一致する部分文字列のスライスを返します。実際のケース: 電子メール アドレスのドメイン名を照合するために使用できます。たとえば、email:="user@example.com", pattern:=@([^\s]+)$ を使用してドメイン名を照合します。 [1]。
