当前位置:网站首页>Go learning notes (83) - code specification and common development skills
Go learning notes (83) - code specification and common development skills
2022-06-26 09:46:00 【wohu1104】
1. Specification guidelines
1.1 Package name
package The naming of should follow the following principles :
- It's just small letters . Does not contain characters such as uppercase letters and underscores ;
- Short and contain some contextual information . for example
time、list、httpetc. ; - It should not be a common name with vague meaning , Or it has the same name as the standard library . For example, you can't use
utilperhapsstrings; - The package name can be used as the path
base name, If the package name string is too long, try to use the directory to split . For example should useencoding/base64instead ofencoding_base64perhapsencodingbase64; - The package name is consistent with the directory , Try to make sense , It is short and concise to represent the main functions of the package , Does not conflict with the standard library , Prevent renaming when importing packages , Full lowercase , Don't underline , Package names are not plural , for example
net/url, instead ofnet/urls;
The following rules shall be satisfied as far as possible in order :
- Do not use common variable names as package names . For example, using
bufioinstead ofbuf; - Use the singular instead of the plural . For example, using
encodinginstead ofencodings; - Use abbreviations carefully . For example, using
fmtBetter than... Without breaking the contextformatShorter , And some names that need to use multiple words to express the context can use abbreviations , For example, usingstrconvinstead ofstringconversion.
1.2 Variable naming
The naming of variables should follow the following principles :
Use... For exportable variables
MixedCaps, For variables used internally, usemixedCaps;Acronyms are capitalized , But when it is at the beginning of a variable and does not need to be exported , Use all lowercase . For example, using
ServeHTTPinstead ofServeHttp, And the use ofXMLHTTPRequestperhapsxmlHTTPRequest;Brevity is better than verbosity . For example, in a cycle , Use
iInstead ofsliceIndex;The farther a variable is from where it is used , The more context information you need to carry . For example, a global variable needs more context information in its name , So that its meaning can be easily recognized in different places ;
The error variable name is usually in
Errperhapserrstart , The hump nomenclature is used later ;It's like a structure , Variable names generally follow the hump method , The initial letter is capitalized or lowercase according to the access control principle , But when it comes to special nouns , The following rules need to be followed :
- If the variable is private , The first word is a special noun , Use lowercase , Such as
apiClient - In other cases, the original form of the noun should be used , Such as
APIClient、repoID、UserID - The wrong sample :
UrlArray, Should be written asurlArrayperhapsURLArray
- If the variable is private , The first word is a special noun , Use lowercase , Such as
If the variable type is
booltype , The name should beHas、Is、CanorAllowstart
var isExist bool
var hasConflict bool
var canManage bool
var allowGitHook bool
1.2 Variable initialization
So we prefer the following form :
var (
a = 13
b = int32(17)
f = float32(3.14)
)
Instead of this seemingly inconsistent form of declaration :
var (
a = 13
b int32 = 17
f float32 = 3.14
)

1.3 Constant naming
Constants named constants are composed of all uppercase letters , And use the underline participle
const APP_VER = "1.0"
1.3 Function name
The naming of functions should follow the following principles :
- For exportable functions, use
MixedCaps, For functions used internally, usemixedCaps; - The function name does not carry the context information of the package name . For example, using
http.Serverinstead ofhttp.HTTPServer, Because package names and function names always appear in pairs . - Keep the function name as short as possible :
- When called
fooThe return type of a function in the packageFoowhen , Type information can often be omitted without ambiguity . For example, usingtime.Now()as well astime.Parse(), Both returntime.Timetype ; - When called
fooThe return type of a function in the packageTwhen (TNot at allFoo), You can add type information to the function name . For example, usingtime.ParseDuration()The return istime.Durationtype ; - When called
fooThe return type of a function in the packageFoo, AndFooIs the entrance to all its methods , have access toNew()To name without ambiguity . For example, usinglist.New()The return is*list.Listtype .
- When called
1.4 Structure
structDeclaration and initialization formats are multiline : The definition is as follows :
type User struct{
Username string
Email string
}
The initialization is as follows :
u := User{
Username: "wohu",
Email: "[email protected]",
}
1.5 Receiver name
The naming of receivers should follow the following principles :
- Do not use common names in object-oriented programming . For example, don't use
self、this、meetc. ; - In general use 1 To 2 An abbreviation of four letters stands for its original type . For example, the type is
Client, have access toc、cletc. ; - Use a uniform abbreviation in each method of this type . For example, in one of the methods
cOn behalf ofClient, In other methods, it is also necessary to usecInstead of using things likeclThe name of ;
recieved Whether the value type or the pointer type is to be used is mainly based on the following principles :
func(w Win) Tally(playerPlayer)int //w There will be no change
func(w *Win) Tally(playerPlayer)int //w It changes the data
1.6 The interface name
The commands of the interface should follow the following principles :
- For a with only one method
interface, It is usually named method name pluser. for exampleReaderandWriter; interfaceDon't use some idiomatic names , Unless this method has the same effect . for exampleRead、Write、Flush、String、ServeHTTP;
1.7 Parameter passing
- For a small amount of data , Don't pass pointers
- For a lot of data
structConsider using pointers - The incoming parameter is
map,slice,chan,interface,stringDon't pass pointers
1.8 The source file name
If you want to use more than one word in the name of the source file , We usually connect multiple words directly as the source file name , Instead of using other separators , Like underline .
in other words , We usually use helloworld.go As a file name instead of hello_world.go . This is because underscores are separators , stay Go Source file naming has a special role .
1.9 Other
- Every base library must have an actual runnable example , The interfaces of the basic library should have unit test cases
- Not in
forUse in circulationdefer,deferOnly when the function exits panicCapture only togoroutineAt the top , Each self initiatedgoroutine, Must be captured at the entrancepanic, And print out the detailed stack informationGoBuilt in typeslice、map、chanAll references , Before initial use , Must first usemakeAssign objects , Otherwise, there will be a null pointer exception- Use
mapNeed to pay attention to :mapFirst use , Must usemakeinitialization ;mapIs quoted , Don't worry about assigning memory copies ; During concurrent operations , It needs to be locked ;rangeWhen traversing, the order is uncertain , Not to be relied upon ; Out of commissionslice、mapandfuncAskey importIn the case of multiple lines ,goimportsIt will automatically format for you , But let's standardize hereimportSome of the norms of , If you introduce a in a filepackage, The following format is recommended :
import (
"fmt"
)
If your package introduces three types of packages , Standard library package , Program internals , Third party package , It is recommended that you organize your package in the following ways :
import (
"encoding/json"
"strings"
"myproject/models"
"myproject/controller"
"myproject/utils"
"github.com/astaxie/beego"
"github.com/go-sql-driver/mysql"
)
Sequential introduction of packages , Different types are separated by spaces , The first is the standard library , The second is the project package , The third is the third-party package .
- Print or call long sentences , Use parameters to format lines We're calling
fmt.Sprintperhapslog.SprintAnd so on , Sometimes I come across very long sentences , We need to split multiple lines at the parameter call :
Here's the wrong way :
log.Printf(“A long format string: %s %d %d %s”, myStringParameter, len(a),
expected.Size, defrobnicate(“Anotherlongstringparameter”,
expected.Growth.Nanoseconds() /1e6))
It should be in the following way :
log.Printf(
“A long format string: %s %d %d %s”,
myStringParameter,
len(a),
expected.Size,
defrobnicate(
“Anotherlongstringparameter”,
expected.Growth.Nanoseconds()/1e6,
),
)
- Notice the call to the closure Call a function or... In a loop
goroutineMethod , Be sure to call with the variables shown , Don't call loop arguments in closure functions
fori:=0;i<limit;i++{
go func(){
DoSomething(i) }() // Wrong way
go func(i int){
DoSomething(i) }(i)// The right way
}
2. Development skills
packageThe name of is the same as the directory name ,mainWith the exception ofstringRepresents an immutable string variable , YesstringThe modification of is a heavy operation , Basically, you need to reapply for memory , If there is no special need , Use more when you need to modify[]byte- Use as much as possible
stringsLibrary operationstring, This can improve performance appendBe careful to automatically allocate memory ,appendThe returned address may be the newly assigned address- If you want to modify it directly
mapOfvaluevalue , bevalueIt can only be a pointer , Otherwise, the original value will be overwritten mapLocking is required in concurrency- The compilation process cannot check
interface{}Transformation , Only runtime checks , Be careful to causepanic - Use
defer, Ensure that resources are released when exiting the function - Use as few global variables as possible , Pass through parameters , Make every function be “ No state ” Of , This reduces coupling , It also facilitates division of labor and unit testing
- If there are many parameters , Define relevant parameters as structure transfer
The code must be formatted after writing , Make sure your code is elegant
gofmt -w main.go,gofmtyesGoIts own formatting tool , Used to organize the code format 、 Space at the end, etc . Reference resources https://pkg.go.dev/cmd/gofmtPerform code static analysis before compiling :
go vet pathxxx/go vetyes Go Built-in tools , Used to check whether the program is correct . Reference resources https://pkg.go.dev/cmd/vet


Race detection :
go build –race( Add... When the test environment is compiled-raceOptions , The production environment must be removed , becauseraceThe limit is at mostgoroutineThe number of 8192 individual )The length of each line is agreed : A line should not be too long , Please use line feed to show more than , Try to keep the format elegant ; Individual files should not be too large , Better not to exceed 500 That's ok
Multiple return values can return up to three , For more than three, please use
structDisable... In logical processing
panic, Unless you know what you're doingThe principle of error handling is not to discard any returned
errCall to , Don't use_discarded , All must be dealt with . Error received , Or go back toerr, Or if it doesn't work, justpanic, Or uselogrecorded . Don't write like this :
if err != nil {
// error handling
} else {
// normal code
}
It should be :
if err != nil {
// error handling
return // or continue, etc.
}
// normal code
3. The robustness of functions
The robust design of functions includes many aspects , The first is the most basic “ Three don't ” principle
Principle one : Do not trust any external input parameters .
The user of the function can be anyone , These people may not have read any manuals or documentation before using the function , They will pass unexpected arguments to the function . therefore , To ensure the robustness of the function , The function needs to check the validity of all input parameters . Once problems are found , Immediately terminate the execution of the function , Returns the default error value .
Principle two : Don't ignore any mistakes .
In our function implementation , Functions or methods provided by standard libraries or third-party packages will also be called . For these calls , We cannot assume that it will succeed , We must explicitly check the error values returned by these calls . Once an error is found , Stop function execution in time , Prevent errors from continuing to propagate .
Principle three : Don't assume that exceptions won't happen .
here , We first need to determine a cognition : Exceptions are not errors . Errors are predictable , It happens often , We have corresponding public error codes and error handling plans , But anomalies are rare 、 Unexpected . An anomaly in the usual sense , Refers to a hardware exception 、 Operating system exception 、 Language runtime exception , There is more likely to be a potential in the code bug The resulting anomaly , For example, the code appears with 0 As denominator , Or the array is accessed beyond the bounds . Although the abnormal occurrence is “ Minority events ”, But we can't assume that exceptions don't happen . therefore , When designing functions , According to the role and usage scenario of the function , Consider whether to set the exception capture and recovery link in the function .
Best practices :
https://github.com/cristaloleg/go-advice/blob/master/README_ZH.md
https://github.com/cristaloleg/go-advice
边栏推荐
- The shutter tabbar listener is called twice
- [pulsar learning] pulsar Architecture Principle
- Introduction to QPM
- [open5gs] open5gs installation configuration
- online trajectory generation
- Deep learning (tentsorflow2. version) three good student performance problems (1)
- Flutter's brain map notes are easy to find and search!
- 我在中山,到哪里开户比较好?在线开户安全么?
- MapReduce&Yarn理论
- Badge series 7: use of codacy
猜你喜欢
QPM suspended window setting information

Notes on sports planning on November 22, 2021

Several connection query methods of SQL (internal connection, external connection, full connection and joint query)

Kubernetes cluster deployment (v1.23.5)

How to solve the problem that NVIDIA model cannot be viewed by inputting NVIDIA SMI and quickly view NVIDIA model information of computer graphics card

Learning to Generalize Unseen Domains via Memory-based Multi-Source Meta-Learning for Person Re-ID

logback

A Style-Based Generator Architecture for Generative Adversarial Networks
![[Journal of Computer Aided Design & computer graphics] overview of research on pedestrian re recognition methods based on generated countermeasure network](/img/a9/1361df052f0474e5c50b948a92c42a.jpg)
[Journal of Computer Aided Design & computer graphics] overview of research on pedestrian re recognition methods based on generated countermeasure network

Detailed explanation of the network security competition questions (2) of the 2021 national vocational college skills competition (secondary vocational group)
随机推荐
【CVPR 2021】DatasetGAN: Efficient Labeled Data Factory with Minimal Human Effort
This new change of go 1.16 needs to be adapted: the changes of go get and go install
Use recursion or a while loop to get the name of the parent / child hierarchy
QPM performance monitoring components - General
【CVPR 2021】Unsupervised Pre-training for Person Re-identification(UPT)
Champions League data set (Messi doesn't cry - leaving Barcelona may reach another peak)
c语言语法基础之——指针(字符、一维数组) 学习
Redis 新手入门
Solve Django's if Version (1, 3, 3): raise improverlyconfigured ('mysqlclient 1.3.3 or new is required
LeetCode 498. 对角线遍历
Badge series 4: use of circle Ci
Common SQL add / delete / modify query statements
halcon 光度立体
Why do some functions in the go standard library have only signatures but no function bodies?
Abnormal record-23
mysql 数据库字段查询区分大小写设置
OpenCV depthframe -> pointcloud 导致 segmentation fault!
MapReduce & yarn theory
Thinkphp5 using the composer installation plug-in prompts that the PHP version is too high
LeetCode 0710. Random numbers in the blacklist - preprocessing implementation o (1) value