Operation

golang 工程构建基础

golang 工程构建基础

1. 打生产包

  • 默认情况打包会增加本地绝对路径,必须去掉本地路径前缀
  • 若包不大,为方便起见,可将使用静态本地 glibc,防止跨不同 linux 内核版本无法执行,否则建议分不同 linux 内核版本打包
# 解决不同平台 glibc 兼容问题. 如: ubuntu在/lib/i386-linux-gnu/libc.so.6, centos在/usr/lib64/libc.so
export CGO_LDFLAGS="-Xlinker -rpath=$(whereis libc.so|sed 's/ /\n/g'|grep libc.so) -static"

export CGO_ENABLED=0
export GOOS=linux
export GOARCH=amd64
export BUILD_VERSION=$(git branch | grep '*' | sed -E 's/\* \(HEAD detached at |\)|\* //g')

go build -v -a \
-ldflags '-s -w' \
-ldflags="-s -X 'main.version=${BUILD_VERSION}'" \
-gcflags="all=-trimpath=$(pwd)" \
-asmflags="all=-trimpath=$(pwd)" \
-o $(pwd)/mybinary

2. 基础类型互转

2.1 float、int、int64、string 类型互转

// string => int
int, err: = strconv.Atoi(string)

// string => int64
// 第三个参数位大小表示期望转换的结果类型,其值可以为0, 8, 16, 32和64,分别对应 int, int8, int16, int32和int64
int64, err := strconv.ParseInt(string, 10, 64)

// string => float
float, err := strconv.ParseFloat(string, 64)
float, err := strconv.ParseFloat(string, 32)

// int => string
string := strconv.Itoa(int)
// 等价于 string := strconv.FormatInt(int64(int), 10)

// int64 => string
string := strconv.FormatInt(int64, 10)

// int => int64
int64 := int64(1234)

// float => string
string := strconv.FormatFloat(float32, 'E', -1, 32)
string := strconv.FormatFloat(float64, 'E', -1, 64)

2.2 int32、string 互转

  • 编写转换函数(最快)

    func String(n int32) string {
    buf := [11]byte{}
    pos := len(buf)
    i := int64(n)
    signed := i < 0
    if signed {
        i = -i
    }
    for {
        pos--
        buf[pos],i = '0'+byte(i%10),i/10
        if i == 0 {
            if signed {
                pos--
                buf[pos] = '-'
            }
            return string(buf[pos:])
        }
    }
    }
  • 使用fmt.Sprint(i)(慢)

// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
func Sprint(a ...interface{}) string {
    p := newPrinter()
    p.doPrint(a)
    s := string(p.buf)
    p.free()
    return s
}
  • 使用strconv.Itoa(int(i))(快速)
// Itoa is shorthand for FormatInt(int64(i),10).
func Itoa(i int) string {
    return FormatInt(int64(i),10)
}
  • 使用strconv.FormatInt(int64(i),10)(更快)
// FormatInt returns the string representation of i in the given base,// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt(i int64,base int) string {
    _,s := formatBits(nil,uint64(i),base,i < 0,false)
    return s
}
  • 比较&基准测试(具有50000000次迭代):
s = String(i)                       takes:  5.5923198s
s = String2(i)                      takes:  5.5923199s
s = strconv.FormatInt(int64(i),10) takes:  5.9133382s
s = strconv.Itoa(int(i))            takes:  5.9763418s
s = fmt.Sprint(i)                   takes: 13.5697761s

测试代码

package main

import (
    "fmt"
    //"strconv"
    "time"
)

func main() {
    var s string
    i := int32(-2147483648)
    t := time.Now()
    for j := 0; j < 50000000; j++ {
        s = String(i) //5.5923198s
        //s = String2(i) //5.5923199s
        //s = strconv.FormatInt(int64(i),10) // 5.9133382s
        //s = strconv.Itoa(int(i)) //5.9763418s
        //s = fmt.Sprint(i) // 13.5697761s
    }
    fmt.Println(time.Since(t))
    fmt.Println(s)
}

func String(n int32) string {
    buf := [11]byte{}
    pos := len(buf)
    i := int64(n)
    signed := i < 0
    if signed {
        i = -i
    }
    for {
        pos--
        buf[pos],i/10
        if i == 0 {
            if signed {
                pos--
                buf[pos] = '-'
            }
            return string(buf[pos:])
        }
    }
}

func String2(n int32) string {
    buf := [11]byte{}
    pos := len(buf)
    i,q := int64(n),int64(0)
    signed := i < 0
    if signed {
        i = -i
    }
    for {
        pos--
        q = i / 10
        buf[pos],i = '0'+byte(i-10*q),q
        if i == 0 {
            if signed {
                pos--
                buf[pos] = '-'
            }
            return string(buf[pos:])
        }
    }
}

参考1: 在 Golang 中将 int32 转换为字符串

3. FAQ

3.1 升级 golang(1.7.3) 后在 VSCode(1.61.0) 中使用 dlv-dap(1.7) debugging 无法进入断点?

// ...
// Ignore others configuration ...
// ...
"go.delveConfig": {
      "debugAdapter": "legacy",
},


3.2 使用 vscode 开发,以 debug 模式运行突然报错 # command-line-arguments src/demo/main/main.go:4:2: undefined: main.go,但直接使用 go run main.go 却正常?

3.3 调试 golang 程序断点处显示 Unverify breakpoint,然后 launch.json中增加"trace": "verbose"后错误日志中显示 Could not found xx/src//xx.go

3.4 dlv版本与golang不兼容,需安装最新

cd $GOROOT/src/$project
go get -v github.com/go-delve/delve/cmd/dlv

留言

您的电子邮箱地址不会被公开。