pointers - golang中slice的地址

标签 pointers go slice

我有这段代码

package main

import (
    "fmt"
)

func Extend(slice []int, element int) []int {
    n := len(slice)
    if n == cap(slice) {
        // Slice is full; must grow.
        // We double its size and add 1, so if the size is zero we still grow.
        newSlice := make([]int, len(slice), 2*len(slice)+1)
        copy(newSlice, slice)
        slice = newSlice
    }
    slice = slice[0 : n+1]
    slice[n] = element
    return slice
}

func main() {
    slice := make([]int, 0, 5)
    for i := 0; i < 10; i++ {
        slice = Extend(slice, i)
        fmt.Printf("len=%d cap=%d slice=%v\n", len(slice), cap(slice), slice)
        fmt.Println("address of 0th element:", &slice[0])
        fmt.Println("address of slice:", &slice) // why does this print the slice and not its address?
        fmt.Printf("address of slice: %p\n", &slice) // why is this different from below? and why does it not change when a new slice is created pointing to a different array?
        fmt.Printf("address of slice: %p\n\n", slice)
    }
}

Playground :https://play.golang.org/p/PWMN-i9_z9

我对循环底部第二个 Println 的问题。如果你运行它,你会看到它打印出 &[values...]。为什么它不打印出地址?我知道您可以使用 Printf 以及其他方法来完成它,并且它有效,但是 Println 呢?带有 &slice[0] 的 Println 工作正常,它打印地址而不是值,但是带有 &slice 的 Println 就像没有。

我还注意到,当我使用 &slice 执行 Printf 语句 %p 时,与仅执行 slice 相比,我得到了不同的地址。为什么?并且带有 &slice 的地址在更改时不会更改(运行它,程序会调整数组的大小并创建一个新的 slice )。但是 printf(%p, slice) 会改变吗?

最佳答案

这就是 fmt.Println 的定义。

来自 https://golang.org/pkg/fmt/#Println :

Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.

在那个页面的前面,描述了默认格式:

For compound objects, the elements are printed using these rules, recursively, laid out like this:

struct:             {field0 field1 ...}
array, slice:       [elem0 elem1 ...]
maps:               map[key1:value1 key2:value2]
pointer to above:   &{}, &[], &map[]

也许你的问题是“为什么”会这样。答案值得商榷,但我想这是因为人们认为以这种形式而不是原始指针显示数据更有用。

您还问为什么修改 slice 不会更改其地址。 slice 是一种值类型(不是 引用类型),它包含指向底层数组的指针(以及它的容量和当前长度)。为 slice 类型的变量分配新值会覆盖该值,但不会更改其地址。 This article on slice use and internals是一个很好的引用。

关于pointers - golang中slice的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29203551/

相关文章:

javascript - 拉斐尔 JS 派 : rotate the slice

python - 使用句点选择/切片多索引数据帧时间序列会导致错误?

c++ - 将结构指针传递给函数 C++

c++ - C++ 中的指针、释放和 vector

parsing - 如何在 Go 的文本/扫描仪中倒带?

Golang 为什么这两个字符串不相等?

c# - 差异 b/n 对象、引用、指针

c - 这段代码在做我想做的事吗?

windows - 戈朗 : Getting started - "go" is not recognized as an internal or external command"

arrays - 紧急运行时错误索引超出范围 [3],长度为 3