go一些技巧
map第二个返回值
go语言的map有第二个返回值,能够判断在map中key是否存在value, ok := kv[key] if !ok { // do something }
_
无视其中一个值
使用_
可以无视多个值中的其中几个或全部_, ok := kv[key] if !ok { // do something }
无视全部值
_, _ := kv[key]
在切片后追加元素
var arr []int arr = append(arr, 1)
在切片前追加元素
var arr []int arr = append([]int{1}, arr...)
在切片后追加多个元素
var arr []int arr = append(arr, []int{1, 2, 3, 4, 5}...)
切片越界
不会越界,是空切片fmt.Println(arr[len(arr):])
会越界
fmt.Println(arr[len(arr)+1:])
会越界
fmt.Println(arr[len(arr)])
弃用标记
// Execer is an optional interface that may be implemented by a Conn. // // If a Conn does not implement Execer, the sql package's DB.Exec will // first prepare a query, execute the statement, and then close the // statement. // // Exec may return ErrSkip. // // Deprecated: Drivers should implement ExecerContext instead (or additionally). type Execer interface { Exec(query string, args []Value) (Result, error) }
BUG标记
// BUG(who): 我是bug说明
包注释
单独doc.go文件package aaa // Execer is an optional interface that may be implemented by a Conn. // // If a Conn does not implement Execer, the sql package's DB.Exec will // first prepare a query, execute the statement, and then close the // statement. // // Exec may return ErrSkip.
Example
文件名example_xxx_test.go
包名xxx_test
函数名func Example[FuncName][_tag]()
函数尾// Output:
```go
// 文件必须放在 banana包目录下, 名字必须为example_xxx_test.go
// Package banana_test 为banana包的示例
package banana_test
// 此注释将会被展示在页面上
// 此函数将被展示在OverView区域
func Example() {
fmt.Println(“Hello OverView”)// Output:
// Hello OverView
}
11. UnitTest
文件名`xxx_test.go`
包名`xxx_test`
函数名`func Test[FuncName][_tag]()`
```go
package server_test
import (
"testing"
"time"
)
func TestServerTimeLayout1(t *testing.T) {
some := time.Now().Format(types.TimeLayout1)
t.Log(some)
}
BenchmarkTest
文件名xxx_test.go
包名xxx_test
函数名func Benchmark[FuncName][_tag]()
package types_test func BenchmarkDataMarshal(b *testing.B) { for i := 0; i < b.N; i++ { data := Data{ MsgType: DeviceReq, Data: []*DeviceS{ { DeviceID: "abc-123_&%S", ServiceID: "discrete", EventTime: "123456", Data: map[string]interface{}{ "LD_14.XY": "0", "LD_15.XY": 0, "LD_16.XY": int64(64), "LD_17.XY": true, "LD_18.XY": 123.456, }, }, }, } _, err := json.Marshal(data) if err != nil { b.FailNow() } // fmt.Println("json", string(bytes)) } }
交换数据
func max(a, b int) { if a > b { a, b = b, a } }
函数返回值定义
func swap(a, b int) (max, min int) { if a > b { max, min = a, b } else { max, min = b, a } return }
safe delete in range
m := map[string]string{ "1": "one", "2": "two", "3": "three", } for key, v := range m { delete(m, key) }
switch可以无参
switch { case a == 3: case b == 4: case c == 7: }
channel写数据时使用default防lock
select { case <-quit: case data<-event: default: }
无类型结构体
// Info 请求可变更字段
type Info struct {
DNSNames []string `json:"dns"` // 证书认证dns
Duration struct {
Year int `json:"year"`
Month int `json:"month"`
Day int `json:"day"`
} `json:"duration"` // 证书有效时间
Path struct {
Servers []struct {
Cert string `json:"cert"`
Key string `json:"key"`
} `json:"servers"`
Clients []struct {
Cert string `json:"cert"`
Key string `json:"key"`
} `json:"clients"`
} `json:"path"`
}
初始化与结构体声明在一起
var opts = struct {
PrintVersion func() `short:"v" long:"version" description:"print the version of the iotx"`
EnableDebug func() `short:"d" long:"debug" description:"enable debug of the iotx"`
}{
PrintVersion: func() {
fmt.Println("Version:", Version)
fmt.Println("BuildTime:", BuildTime)
os.Exit(0)
},
EnableDebug: func() {
logrus.SetLevel(logrus.DebugLevel)
},
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wind.kaisa@gmail.com