英文:
Why Golang object property of byte array will be wiped when assigned to another variable
问题
我们需要在使用后清除一些变量。但是当它被赋值给结构体中的[]byte
字段时,这似乎非常奇怪。
为什么这个[]byte
的赋值不是一个拷贝,而是一个指针?
我应该怎么做才能保留结构体a.bs
中的值,但清除作为局部变量的b
?
package main
import "fmt"
type so struct {
bs []byte
}
func zeroes(n int) []byte {
return make([]byte, n)
}
func wipeBytes(b []byte) {
copy(b, zeroes(len(b)))
}
func main() {
a := so{bs: []byte{0x01, 0x02}}
b := a.bs
wipeBytes(b)
fmt.Println(b) //b == []byte{}
fmt.Println(a.bs) //a.bs == []byte{}
}
链接:http://play.golang.org/p/MT_wAHj2OM
英文:
We need to wipe out some variables after use. But it seems really weird when it's assigned with a []byte
field in a struct.
Why this assignment of []byte
is not a copy but a pointer?
What should I do to keep the value in struct a.bs
, but wipe out the b
as local variable?
http://play.golang.org/p/MT_wAHj2OM
package main
import "fmt"
type so struct {
bs []byte
}
func zeroes(n int) []byte {
return make([]byte, n)
}
func wipeBytes(b []byte) {
copy(b, zeroes(len(b)))
}
func main() {
a := so{bs: []byte{0x01, 0x02}}
b := a.bs
wipeBytes(b)
fmt.Println(b) //b == []byte{}
fmt.Println(a.bs) //a.bs == []byte{}
}
答案1
得分: 1
切片本质上是引用类型。分配一个切片并不会复制其内容。你可以将切片值看作是一个“切片头”结构,其中包含指向切片底层数组的指针,以及切片在数组中的偏移量和长度。当你复制切片时,复制的是这个结构,而不是数组中的任何值。
你可以使用以下代码:
b := make([]byte, len(a.bs)))
copy(b, a.bs)
将b
创建为一个新的切片,并将a.bs
的内容复制到其中。然后,对其中一个切片所做的任何操作都不会影响另一个切片。
英文:
Slices are inherently reference-y things. Assigning one doesn't copy its contents. You can think of a slice value as being a "slice head" structure, which contains a pointer to the slice's underlying array, and the offset and length of the slice within the array. It's this structure that's copied when you copy the slice, not any of the values in the array.
You can do
b := make([]byte, len(a.bs)))
copy(b, a.bs)
to make b
a new slice and copy a.bs
's contents into it. Then nothing you do to one will have any effect on the other.
答案2
得分: 1
在声明/创建array
([]byte{0x01, 0x02}
)时,你没有指定长度([2]byte{0x01, 0x02}
),这意味着它是一个切片而不是数组。切片对象在内部包含指向其内容的指针。
英文:
When declaring/creating the 'array' ([]byte{0x01, 0x02}
), you're not specifying a length ([2]byte{0x01, 0x02}
), which means that it's a slice instead of an array. And slices objects internally contains a pointer to it's content.
答案3
得分: 0
func ObjectAssign(target interface{}, object interface{}) {
// 将 object 的属性值赋给 target 的属性值
// 使用模式匹配(https://golang.org/pkg/reflect/#Value.FieldByName)
// 参考:https://stackoverflow.com/questions/35590190/how-to-use-the-spread-operator-in-golang
t := reflect.ValueOf(target).Elem()
o := reflect.ValueOf(object).Elem()
for i := 0; i < o.NumField(); i++ {
for j := 0; j < t.NumField(); j++ {
if t.Field(j).Name() == o.Field(i).Name() {
t.Field(j).Set(o.Field(i))
}
}
}
}
英文:
func ObjectAssign(target interface{}, object interface{}) {
// object atributes values in target atributes values
// using pattern matching (https://golang.org/pkg/reflect/#Value.FieldByName)
// https://stackoverflow.com/questions/35590190/how-to-use-the-spread-operator-in-golang
t := reflect.ValueOf(target).Elem()
o := reflect.ValueOf(object).Elem()
for i := 0; i < o.NumField(); i++ {
for j := 0; j < t.NumField(); j++ {
if t.Field(j).Name() == o.Field(i).Name() {
t.Field(j).Set(o.Field(i))
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论