Pointers 非常混乱的变量变化

Pointers 非常混乱的变量变化,pointers,struct,go,race-condition,Pointers,Struct,Go,Race Condition,我在Go中有一些上下文无关语法的代码 我看了这么多次这段代码,仍然没有看到任何改变结构值的理由。有人知道为什么会发生这样的变化吗 规则: S->。[DP-VP] VP->。[V DP] VP->。[V DP AdvP] 在我运行了一些函数之后 or2 = append(or2, OstarCF([]QRS{q}, []string{"sees"}, g2.Nullables(), g2.ChainsTo(g2.Nullables()))...) 不知怎的,我的结构值改变了。。。我不知道为什

我在Go中有一些上下文无关语法的代码

我看了这么多次这段代码,仍然没有看到任何改变结构值的理由。有人知道为什么会发生这样的变化吗

规则:
S->。[DP-VP]
VP->。[V DP]
VP->。[V DP AdvP]

在我运行了一些函数之后

 or2 = append(or2, OstarCF([]QRS{q}, []string{"sees"}, g2.Nullables(), g2.ChainsTo(g2.Nullables()))...)
不知怎的,我的结构值改变了。。。我不知道为什么

规则:
S->。[VP]
VP->。[DP]
VP->。[AdvP AdvP]

这本应与上述内容相同

 Rules:
 S -> DP,VP
 VP -> V,DP
 VP -> V,DP,AdvP

 or2 := []QRS{}
 g2 := ToGrammar(cfg2)
 fmt.Printf("%s\n", g2)

 for _, rule := range g2.Rules {
        q := QRS{
            one:   rule.Src,
            two:   []string{},
            three: rule.Right,
        }
        or2 = append(or2, OstarCF([]QRS{q}, []string{"sees"}, g2.Nullables(), g2.ChainsTo(g2.Nullables()))...)
    }

    fmt.Printf("%s\n", g2)
正如您所看到的,我没有使用任何指针作为变量规则,它们只用于实例化另一个结构值,但是为什么原始结构字段规则发生了变化?函数OstarCF不处理此字段规则


原始规则字段会发生更改,因为使用了指针和切片(它们也是引用)

在调用OstarCF之前,将调用ChainsTo方法。它按值使用语法对象,因此完成了复制,但规则字段是规则上的一片指针。因此,复制此字段时,它仍然指向原始对象的数据

然后,在方法ChainsTo中,规则字段上有一个循环。它复制右字段,右字段是字符串的一部分(因此它仍然指向原始对象的数据):

最后,通过切片rhs声明ns变量:

ns := rhs[:i]
ns = append(ns, rhs[i+1:]...)
在这个阶段,ns变量仍然指向包含原始对象的字符串片段的缓冲区。最初,i=0,因此ns是一个空片,用于重用缓冲区。追加项时,它们将替换原始数据

这就是您的数据被更改的原因

您可以通过显式制作副本来解决此问题,例如,通过将上述行替换为:

ns := make( []string, 0, len(rhs) )
ns = append( ns, rhs[:i]...)
ns = append( ns, rhs[i+1:]...)
Go切片已经取代了C指针算法,但在某些情况下它们几乎同样危险/误导

ns := rhs[:i]
ns = append(ns, rhs[i+1:]...)
ns := make( []string, 0, len(rhs) )
ns = append( ns, rhs[:i]...)
ns = append( ns, rhs[i+1:]...)