当前位置: 首页 > 面试题库 >

切片结构vs指向结构的指针

叶稳
2023-03-14
问题内容

我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * Widget,然后将输出10和11。

为什么是这样?

package main

import (
    "fmt"
)

func main() {

    type Widget struct {
        id    int
        attrs []string
    }

    widgets := []Widget{
        Widget{
            id:    10,
            attrs: []string{"blah", "foo"},
        },
        Widget{
            id:    11,
            attrs: []string{"foo", "bar"},
        },
        Widget{
            id:    12,
            attrs: []string{"xyz"},
        },
    }

    var matches []*Widget
    for _, w := range widgets {
        for _, a := range w.attrs {
            if a == "foo" {
                matches = append(matches, &w)
                break
            }
        }
    }

    for _, m := range matches {
        fmt.Println(m.id)
    }

}

问题答案:

那是因为当您使用指针时,您将添加&w到数组。

请注意,w实际上这是循环中使用的局部变量,因此,这不是您要添加到matches数组中的地址。

(即使变量的 w在循环中发生变化,其 地址也 保持不变)

循环结束时,w以最后一个值结束,这就是为什么它打印12两次的原因。

您需要添加匹配的元素的地址。

如果您这样做:

matches = append(matches, &widgets[i])

然后它也可以很好地与指针一起工作。

修改后的Go游乐场供您测试:

https://play.golang.org/p/YE-cokyEHu



 类似资料:
  • 我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为new

  • 问题内容: 我想有一个通用的方法,无论它是作为指针,切片还是数组提供的,都将始终返回结构值。 我对此的处理方式如下: 去游乐场 如您所见,问题出在从a 或。中获取结构。 我如何扩展上面的函数以从数组或切片中获取struct的值? 更新:我要做的就是将变成。 问题答案: 如果你只是想要的类型,即使片是零,你可以使用像这样: 关于,来自http://golang.org/pkg/reflect/#Ty

  • Go 语言中指向结构体的指针和 C 语言一样 结构体和指针 创建结构体指针变量有两种方式 package main import "fmt" type Student struct { name string age int } func main() { // 创建时利用取地址符号获取结构体变量地址 var p1 = &Student{"lnj", 33}

  • 问题内容: 另一个链接的问题是在使用strcpy()时出现细分错误吗? 我有一个结构: 如何初始化指向上述类型结构的指针,以及如何初始化指向结构内部的10个字符串(incall [])的指针。 我首先初始化字符串,然后初始化结构。 谢谢。 编辑:我猜我用错了字,应该说分配。实际上,我将此结构作为线程的参数传递。线程数不是固定的,作为参数发送的数据结构对于每个线程都必须是唯一的,并且是“线程安全的”

  • 问题内容: 我看到一些具有以下构造的代码示例: 我有C ++背景,对我来说似乎是错误。这种结构的语义是什么?是否在堆栈或堆上分配了新点? 问题答案: Go执行指针转义分析。如果指针转义了本地堆栈(在这种情况下会这样做),则在堆上分配对象。如果它没有对本地函数进行转义,则编译器可以自由地在堆栈上分配它(尽管它不作任何保证;这取决于指针转义分析是否可以证明该指针在该函数中保持局部)。