4. func startServer(host string, config *Config)
func startServer(host string, c *Config)
userMap := make(map[string]*User)
users := make(map[string]*User)
func CountFemale(people []Person) int {
c := 0
for i, p := range people {
if p.gender == "F" {
c++
}
}
return c
}
How to make variable names more clear?
5. Short Names
o Where the types are descriptive, they should be short.
o Where the types are more ambiguous, the names may provide
documentation.
o The greater the distance between a name's declaration and
its uses, the longer the name should be.
- Andrew Google Inc. What‘s in a name?
6. Short Names
o Single letter for method receivers, loops and branches.
o Single words for parameters and local variables.
o Two words for methods.
7. Short Names
o ‘i' to index
o ‘w’ to writer
o ‘r’ to reader
o ‘b’ to buffer
o ‘ok’ check if the key exists in the map
8. Names without their types
usersMap := make(map[string]*User)
users := make(map[string]*User) Preferred
o The name of the variable should describe its contents,
not the type of the contents.
- Dave Cheney. Practical Go
9. Names
Use a consistent naming style
A good name is it should be predictable
- Dave Cheney. Practical Go
11. Declaration Style
var – Declare a variable without initialization
:= - Declare and initialize a variable
var stdnt Student Preferred
stdnt := Student{Name: "Cherie"}
stdnt := Student{}
12. Declaration Style
o nil Slice and non-nil Slice
var stdnts []Student Preferred
stdnts = make([]Student, 0) // For encoding JSON objects
14. Packages
o Do not put all types inside a models folder.
o Avoid package names like base, common, or util.
Its name doesn’t reflect its purpose, only its function in
breaking the import cycle.
15. Packages
o Avoid mutable package-global state
It is difficult to write unit tests.
May cause bugs in complex projects.
18. API Design
o Avoid taking several parameters of the same type.
// Example:
func Extract(source, target, destination string) error {
// Implementation
}
APIs with multiple parameters of the same type are hard to
use correctly. - Dave Cheney
19. API Design
o Carefully using nil as parameters.
// Bad
func DoSomething(cfg *customConfig) {
if cfg == nil {
// Use default config
}
}
DoSomething(nil)
21. Functional options
o A common way to apply your configuration
type Configuration struct {
Port int
Addr string
}
func NewServer(config *Configuration) {
//
}
22. Functional options
func NewServer(opts ...Option) {
cfg := Configuration{
Port: 8080,
Addr: "localhost"
}
// Use option functions to modify your default configuration
for _, opt := range opts {
opt(&cfg)
}
}
func ChangePort(v int) Option {
return func(cfg *Configuration){
cfg.Port = v
}
}
o A better way by using functional options
23. Functional options
// Example - gRPC
s := grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))
// Example - MongoDB
client, err := mongo.NewClient(options.Client().ApplyURI(”.."))
24. Dependency Injection
// Example
func main() {
cfg := GetConfig()
db, err := ConnectDatabase(cfg.URN)
if err != nil {
panic(err)
}
repo := NewPersonRepository(db)
service := NewPersonService(cfg.AccessToken, repo)
server := NewServer(cfg.ListenAddr, service)
server.Run()
}
25. Dependency Injection
o Choose a good way to manage package dependency
v Framework (Dig)
v Code Generator (Google-Wire)
27. Sr. Software Engineer – IIOT security
o 2-3
o
o
We are looking for an experienced Software Engineer to develop the
backend management server for an industrial IoT security project.
29. References
1. Practical Go: Real world advice for writing maintainable Go programs
https://dave.cheney.net/practical-go/presentations/qcon-china.html
2. GopherCon EU 2018: Peter Bourgon - Best Practices for Industrial Programming
https://www.youtube.com/watch?v=PTE4VJIdHPg
3. What's in a name
https://talks.golang.org/2014/names.slide#1
4. Organize your code with Go packages
https://blog.learngoprogramming.com/code-organization-tips-with-packages-d30de0d11f46
5. Idiomatic Go
https://dmitri.shuralyov.com/idiomatic-go