Go 语言中的引用类型令人困惑
Posted
技术标签:
【中文标题】Go 语言中的引用类型令人困惑【英文标题】:Reference type confusing in Go language 【发布时间】:2015-02-26 07:48:12 【问题描述】:我试图用 Go 语言制作 Trie 数据结构,但不知何故它遇到了引用问题, 这里是。 http://play.golang.org/p/ASSGF5Oe9R
// Package main provides ...
package main
import "fmt"
type RootTrie []Trie
type Trie struct
subtrie []Trie
index byte
func (trie *Trie) Insert(data string) *Trie
if data != ""
if trie.index == 0
trie.index = data[0]
if next := trie.containsIndex(data[1:]); next != nil
//Problem Point
fmt.Println(string(data[1]), "found follwing", string(data[0]))
next.Insert(data[1:])
else
nt := &Trie
trie.subtrie = append(trie.subtrie, *nt.Insert(data[1:]))
return trie
func (trie *Trie) containsIndex(next string) *Trie
if next != ""
for _, st := range trie.subtrie
if st.index == next[0]
return &st
return nil
func main()
t := &Trie
t = t.Insert("hanyang")
fmt.Println("result:", t)
t = t.Insert("hanyKk")
fmt.Println("result:", t)
t.Insert("hanyK")
在第二个“插入”中出现以下问题,
我放的地方,//Problem Point
我制作了containsIndex
方法来搜索下一个链接的trie,它实际上搜索得很好。
但是当我更新containsIndex
给出的next
属性时,它并没有影响它的母结构trie
。
我不明白的是我在返回 containsIndex
时给了它引用类型,但它仍然
行为喜欢'价值复制',为什么它不影响其母结构(trie
)?
谢谢!
【问题讨论】:
我不明白 -1 - 存在语言障碍,但它解释了问题的本质,并且有代码可以乱七八糟。 【参考方案1】:问题出在方法 containsIndex 中。 Golang range
默认情况下会在 slice 中创建每个元素的副本,并将该值的副本分配给 st
(在您的示例中)。通常要保留对切片中元素的引用,您应该使用原始切片及其索引。在您的情况下,方法 containsIndex 应该如下所示:
func (trie *Trie) containsIndex(next string) *Trie
if next != ""
for i, st := range trie.subtrie
if st.index == next[0]
return &trie.subtrie[i]
return nil
【讨论】:
这是否也意味着仅使用索引而不是值时的性能差异? @EtienneBruines——也许吧。它可能可以忽略不计,或者如果编译器认识到它有时可以优化副本,则可能没有区别。如果您在性能关键的内部循环中遇到这种选择,您可以随时进行测试。 @twotwotwo 感谢您的回复。我运行了一些基准测试:在不复杂的情况下,根本没有性能差异。 github.com/EtienneBruines/go-range-performance-analysis 谢谢,@wonsky。我在那里找到了一些有趣的答案,我检查了地址差异link以上是关于Go 语言中的引用类型令人困惑的主要内容,如果未能解决你的问题,请参考以下文章
go语言学习笔记 — 基础 — 基本数据类型 — 类型类别:值类型和引用类型