Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GO-WaitGroups引用中的指针或变量_Go_Pointers_Variables - Fatal编程技术网

GO-WaitGroups引用中的指针或变量

GO-WaitGroups引用中的指针或变量,go,pointers,variables,Go,Pointers,Variables,根据sync包中的以下函数声明: Add------>func(wg*WaitGroup)Add(delta int) 完成------->func(wg*WaitGroup)完成() Wait----->func(wg*WaitGroup)Wait() 我知道这三个都是由指向WaitGroup的指针调用的,对吗 如果这是正确的,我不明白在下一段代码中,为什么使用指针变量调用Done函数,而使用变量(而不是指针)调用Add和Wait函数: 主程序包 进口( “fmt” “同步” “时间” )

根据sync包中的以下函数声明:

Add------>func(wg*WaitGroup)Add(delta int)

完成------->func(wg*WaitGroup)完成()

Wait----->func(wg*WaitGroup)Wait()

我知道这三个都是由指向WaitGroup的指针调用的,对吗

如果这是正确的,我不明白在下一段代码中,为什么使用指针变量调用Done函数,而使用变量(而不是指针)调用Add和Wait函数:


主程序包
进口(
“fmt”
“同步”
“时间”
)
func worker(id int,wg*sync.WaitGroup){
推迟工作组完成()
fmt.Printf(“工人%d开始\n”,id)
时间。睡眠(时间。秒)
fmt.Printf(“工作程序%d已完成\n”,id)
}
func main(){
var wg sync.WaitGroup

对于i:=1;iDone,在指针上调用Add和Wait。所有函数都引用指针接收器*WaitGroup。将变量声明为WaitGroup的值并不意味着所有这些方法都将访问和修改该变量。唯一的问题是当您想将变量传递给worker时——如果您试图将其作为v传递您将创建一个副本,然后Done将引用与Add和Wait不同的指针-这就是为什么您用&传递它的地址

我认为这是迄今为止我在这个话题上看到的最好的解释:

一般来说,当你有一个类型的变量时,你几乎可以对它调用任何你想调用的东西。当你把以上两条规则结合在一起时,以下是有效的:

type List []int

func (l List) Len() int        { return len(l) }
func (l *List) Append(val int) { *l = append(*l, val) }

func main() {
    // A bare value
    var lst List
    lst.Append(1)
    fmt.Printf("%v (len: %d)\n", lst, lst.Len())

    // A pointer value
    plst := new(List)
    plst.Append(2)
    fmt.Printf("%v (len: %d)\n", plst, plst.Len())
}
请注意,指针和值方法都可以对指针和非指针值调用。为了了解原因,让我们直接从规范中检查这两种类型的方法集:

List
- Len() int

*List
- Len() int
- Append(int) 
请注意,为List设置的方法实际上并不包含Append(int),即使您可以从上面的程序中看到可以毫无问题地调用该方法。这是上面第二个规范部分的结果。它隐式地将下面的第一行转换为第二行:

lst.Append(1)
(&lst).Append(1)
现在点之前的值是*列表,它的方法集包括Append,调用是合法的


<> >为了更容易记住这些规则,简单地考虑指针和值接收器方法与方法集是有帮助的。将指针值方法调用任何已经是指针或可以使用其地址的方法是合法的(如上面例子中的情况).对任何值或其值可以取消引用的对象调用value方法都是合法的(与任何指针的情况一样;这种情况在规范中明确指定)。

请参阅:“如果方法集(的类型)为,则方法调用x.m()是有效的。”x包含m,参数列表可以指定给m的参数列表。如果x是可寻址的,并且&x的方法集包含m,则x.m()是(&x).m()的简写形式它们都是用指针接收器来呼叫的。参见和,等等。这在巡演中有解释。非常感谢:mkopriva,JimB,迪斯科赞美诗。我会努力学习和理解你们为我写的解释。非常感谢。非常感谢Kamil。我会努力学习和理解你们为我写的解释。
lst.Append(1)
(&lst).Append(1)