golang 进入中附加的各种操作

保存自https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.6.md

append.go
将切片 b 的元素追加到切片 a 之后:a = append(a, b...)

复制切片 a 的元素到新的切片 b 上:

b = make([]T, len(a))
copy(b, a)
删除位于索引 i 的元素:a = append(a[:i], a[i+1:]...)

切除切片 a 中从索引 i 至 j 位置的元素:a = append(a[:i], a[j:]...)

为切片 a 扩展 j 个元素长度:a = append(a, make([]T, j)...)

在索引 i 的位置插入元素 x:a = append(a[:i], append([]T{x}, a[i:]...)...)

在索引 i 的位置插入长度为 j 的新切片:a = append(a[:i], append(make([]T, j), a[i:]...)...)

在索引 i 的位置插入切片 b 的所有元素:a = append(a[:i], append(b, a[i:]...)...)

取出位于切片 a 最末尾的元素 x:x, a = a[len(a)-1], a[:len(a)-1]

将元素 x 追加到切片 a:a = append(a, x)

golang 字节数组对比函数

返回两个字节数组字典顺序的整数对比结果,如果a == b则为0,如果a <b则为-1,如果a> b则为-1。

compare.go
func Compare(a, b[]byte) int {
    for i:=0; i < len(a) && i < len(b); i++ {
        switch {
        case a[i] > b[i]:
            return 1
        case a[i] < b[i]:
            return -1
        }
    }
    // 数组的长度可能不同
    switch {
    case len(a) < len(b):
        return -1
    case len(a) > len(b):
        return 1
    }
    return 0 // 数组相等
}

golang 修改字符串中的某个字符

先将字符串转换成字节数组,然后再通过修改数组中的元素值来达到修改字符串的目的,最后将字节数组转换回字符串格式。

change_str.go
s := "hello"
c := []byte(s)
c[0] = 'c'
s2 := string(c) // s2 == "cello"

golang 自定义切片追加方法

func append(s [] T,x ... T)[] T其中append方法将0个或多个具有相同类型s的元素追加到切片后面并且返回新的切片;

AppendByte.go
func AppendByte(slice []byte, data ...byte) []byte {
	m := len(slice)
	n := m + len(data)
	if n > cap(slice) { // if necessary, reallocate
		// allocate double what's needed, for future growth.
		newSlice := make([]byte, (n+1)*2)
		copy(newSlice, slice)
		slice = newSlice
	}
	slice = slice[0:n]
	copy(slice[m:n], data)
	return slice
}

golang 通过缓冲串联字符串

保存自https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.2.md

buffer.go
var buffer bytes.Buffer
for {
	if s, ok := getNextString(); ok { //method getNextString() not shown here
		buffer.WriteString(s)
	} else {
		break
	}
}
fmt.Print(buffer.String(), "\n")

golang 实现一个where()闭包函数来打印函数执行的位置

包运行时中的函数Caller()提供了相应的信息;也可以设置log包中的flag参数来实现

Caller.go
log.SetFlags(log.Llongfile)
log.Print("")


where := func() {
	_, file, line, _ := runtime.Caller(1)
	log.Printf("%s:%d", file, line)
}
where()
// some code
where()
// some more code
where()
FuncWhere.go
var where = log.Print
func func1() {
where()
... some code
where()
... some code
where()
}

golang 工厂函数

一个返回值为另一个函数的函数可以被称之为工厂函数,这在您需要创建一系列相似的函数的时候非常有用:书写一个工厂函数而不是针对每种情况都书写一个函数下面的函数演示了如何动态返回追加后缀的函数:

MakeAddSuffix.go
func MakeAddSuffix(suffix string) func(string) string {
	return func(name string) string {
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}
		return name
	}
}

golang 记录函数参数返回值

defer_logvalues.go
package main

import (
	"io"
	"log"
)

func func1(s string) (n int, err error) {
	defer func() {
		log.Printf("func1(%q) = %d, %v", s, n, err)
	}()
	return 7, io.EOF
}

func main() {
	func1("Go")
}

golang 延迟实现代码追踪

defer_tracing.go
package main

import "fmt"

func trace(s string) string {
	fmt.Println("entering:", s)
	return s
}

func un(s string) {
	fmt.Println("leaving:", s)
}

func a() {
	defer un(trace("a"))
	fmt.Println("in a")
}

func b() {
	defer un(trace("b"))
	fmt.Println("in b")
	a()
}

func main() {
	b()
}

golang 使用位左移与iota计数配合可优雅地实现存储单位的常量枚举

使用位左移与iota计数配合可优雅地实现存储单位的常量枚举

ByteSize.go
type ByteSize float64
const (
	_ = iota // 通过赋值给空白标识符来忽略值
	KB ByteSize = 1<<(10*iota)
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)