Golang内置函数之copy用法及用例
1. 该函数主要是切片(slice)的拷贝,不支持数组
2. 将第二个slice里的元素拷贝到第一个slice里,拷贝的长度为两个slice中长度较小的长度值
常规用法
// 常规用法
s1 := []int{1,2,3}
s2 := []int{4,5,6,7,8,9}
// s1长度比s2长度短,以len(s1)=3的长度复制
// 所以会将4,5,6覆盖掉1,2,3
// 所以下面s1打印出来为[4, 5, 6]
// copy函数会返回复制的长度
n := copy(s1, s2)
fmt.Println(s1) //[4 5 6]
fmt.Println(n) // 3
特殊用法(将字符串当成[]byte类型的slice)
bytes := []byte("hello world")
// 可以直接将字符串拷贝进[]byte里边
// 由于拷贝的长度为两个slice中长度较小的长度值,
// n返回的就是两个slice中长度较小的长度值
n := copy(bytes,"he he")
fmt.Println(n) // n = len("ha ha") = 5
// 那么长度较短的字符串将会替换掉bytes里长度较长的字符串的前面的部分
// 那么就会打印出"he he world", "hello word"长度为11,
// "hello"长度为5, “he he"长度为5,
// 所以”hello“被替换成了"he he"
fmt.Println(string(bytes)) // "he he world"
stirngs.Join()中的copy使用
func Join(a []string, sep string) string {
switch len(a) {
case 0:
return ""
case 1:
return a[0]
case 2:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1]
case 3:
// Special case for common small values.
// Remove if golang.org/issue/6714 is fixed
return a[0] + sep + a[1] + sep + a[2]
}
// 计算拼接后的字符串长度
n := len(sep) * (len(a) - 1) // 分隔符的总长度(需要多少个分隔符就把它们的长度都加起来)
for i := 0; i < len(a); i++ { // 然后n加上各个字符串加起来的长度
n += len(a[i])
}
b := make([]byte, n)
bp := copy(b, a[0])
// 将字符串当成[]byte类型的slice, 并添加进去
// copy会返回两个参数中长度较短的那个参数的长度
// 循环遍历剩余的字符串, 并把字符串添加进b([]byte)中
for _, s := range a[1:] {
// 以返回的长度为下标并在这个slice后面添加分隔符(sep), 并把bp当前长度记住
bp += copy(b[bp:], sep)
// 以返回的长度为下标并在这个slice后面添加字符串(s), 并把bp当前长度记住
bp += copy(b[bp:], s)
}
return string(b)
}
小插曲, 如果是用自己的想法改写Join函数(不使用copy函数)
// MyJoin 自定义join函数
func MyJoin(s []string, sep string) string {
switch len(s) {
case 0:
return ""
case 1:
return s[0]
case 2:
return s[0] + sep + s[1]
case 3:
return s[0] + sep + s[1] + sep + s[2]
}
// 主要修改部分,个人想法
var values string
for i, v := range s {
if i == len(s)-1 {
values += v
break
}
value := v + sep
values += value
}
return values
}