Pointers 附加到片的元素的地址
我想创建元素,将其添加到切片中,并根据其地址对其进行更改。我希望元素从外部的变化也会改变一个片段。但是在添加之后,会创建一个新的切片。我使用序列化,所以使用一个地址片是不合适的,而且元素的添加发生在不同的goroutine中,所以访问最后添加的元素也是不合适的Pointers 附加到片的元素的地址,pointers,variables,go,slice,Pointers,Variables,Go,Slice,我想创建元素,将其添加到切片中,并根据其地址对其进行更改。我希望元素从外部的变化也会改变一个片段。但是在添加之后,会创建一个新的切片。我使用序列化,所以使用一个地址片是不合适的,而且元素的添加发生在不同的goroutine中,所以访问最后添加的元素也是不合适的 package main import ( "fmt" ) func main() { var a []int b := 1 fmt.Println("old addr:", &b) /
package main
import (
"fmt"
)
func main() {
var a []int
b := 1
fmt.Println("old addr:", &b)
// old addr: 0x10414020
a = append(a, b)
fmt.Println("new addr:", &a[0])
// new addr: 0x10414028
}
引用的程序行为完全正确-地址表示存储位置,
b int
是一个这样的位置,而片中的元素是另一个
您很可能需要存储指针而不是int
s
现在,关于序列化,我不确定您的想法是什么,但一般来说,您可以按照以下方式进行:
type myArray []*int
var a myArray
//...
func (x myArray) Serialize() []byte { .... }
其中,
Serialize
满足序列化程序使用的接口。这不是创建新切片标头和备份数组的问题
这是将b
附加到切片a
的问题,将附加b
变量值的副本。您可以附加一个值,而不是一个变量!顺便说一下,追加(或赋值)会生成所追加(或赋值)值的副本
请注意,如果您不调用append()
,而是预先分配片并将b
分配给a[0]
,则b
和a[0]
的地址也将不同:
var a = make([]int, 1)
b := 1
fmt.Println("old addr:", &b)
// old addr: 0x10414024
a[0] = b
fmt.Println("new addr:", &a[0])
// new addr: 0x10414020
试穿一下
这是因为变量b
和a
是不同的变量;或者更准确地说,变量b
和a
的后备数组为其元素保留内存(包括a[0]
的内存空间),因此它们的地址不能相同
不能创建放置在另一个变量相同内存位置的变量。为了达到这个“效果”,你手上有指针。您必须创建一个指针变量,可以将其设置为指向另一个现有变量。通过访问和修改指针值,您实际上是在访问和修改存储在指针中地址的变量
如果要将“某物”存储在a
切片中,通过该切片可以访问和修改“outsier”b
变量,最简单的方法是存储其地址,其类型为*int
例如:
var a []*int
b := 1
fmt.Println("b's addr:", &b)
a = append(a, &b)
fmt.Println("addr in a[0]:", a[0])
// Modify b via a[0]:
*a[0] = *a[0] + 1
fmt.Println("b:", b)
输出(在上尝试):
赋值总是让运行时为复制的值分配新内存,并且分配的内存将有另一个地址。如果附加到一个值片,则始终会复制变量
如果必须从不同的go例程访问元素,则必须使其线程安全。无论您使用的是值还是引用,都必须这样做。只需使用指针片段var a[]*int示例—正如@Uvelichitel所指出的—也可以使用指针片段;但是,OP必须确保它们确实有几个不同的
b
s将它们的地址放入该片中。谢谢,我必须使用指针数组并重写序列化。
b's addr: 0x10414020
addr in a[0]: 0x10414020
b: 2