Golang中如何将引用传递给函数

Golang中如何将引用传递给函数 https://play.golang.org/p/36HbIQRXQAm

我需要将切片的引用传递给函数,但有些问题,因为遍历切片时没有输出任何数据。

package main

import (
	"fmt"
)

func main() {

	timeMarkers := []string{}

	go timeMarkersSearch(&timeMarkers)

	for _, marker := range timeMarkers {
		fmt.Println(marker)
	}

}

func timeMarkersSearch(timeMarkers *[]string) {
	s1 := "s1"
	s2 := "s2"
	*timeMarkers = append(*timeMarkers, s1)
	*timeMarkers = append(*timeMarkers, s2)
}

更多关于Golang中如何将引用传递给函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

没有问题,但 main 函数在 goroutine 添加任何元素之前就打印了空切片。

你可以移除 go 关键字,或者使用 sync.WaitGroup 来同步你的 goroutine,就像我在 playground 上做的那样

func main() {
    fmt.Println("hello world")
}

更多关于Golang中如何将引用传递给函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你不需要为此使用 sync.WaitGroup。你可以简单地使用一个完成通道。这是重构后的代码

我也认为你可能想改用通道,像这样

在 Go 语言中,你通过指针传递切片引用是正确的,但问题在于主 goroutine 和 timeMarkersSearch goroutine 之间存在竞态条件。主 goroutine 在启动 timeMarkersSearch 后立即开始遍历切片,而此时 timeMarkersSearch 可能还没有完成向切片添加元素的操作。

以下是修正后的代码,使用 sync.WaitGroup 来同步两个 goroutine:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	timeMarkers := []string{}

	wg.Add(1)
	go timeMarkersSearch(&timeMarkers, &wg)

	wg.Wait() // 等待 timeMarkersSearch 完成

	for _, marker := range timeMarkers {
		fmt.Println(marker)
	}
}

func timeMarkersSearch(timeMarkers *[]string, wg *sync.WaitGroup) {
	defer wg.Done()
	s1 := "s1"
	s2 := "s2"
	*timeMarkers = append(*timeMarkers, s1)
	*timeMarkers = append(*timeMarkers, s2)
}

在这个修正版本中:

  • 添加了 sync.WaitGroup 来确保主 goroutine 等待 timeMarkersSearch 完成
  • timeMarkersSearch 函数接收 WaitGroup 指针参数,并在函数结束时调用 Done()
  • 主函数在启动 goroutine 后调用 wg.Wait() 等待

输出结果:

s1
s2

另一种更简洁的方式是避免使用 goroutine,直接调用函数:

package main

import (
	"fmt"
)

func main() {
	timeMarkers := []string{}

	timeMarkersSearch(&timeMarkers)

	for _, marker := range timeMarkers {
		fmt.Println(marker)
	}
}

func timeMarkersSearch(timeMarkers *[]string) {
	s1 := "s1"
	s2 := "s2"
	*timeMarkers = append(*timeMarkers, s1)
	*timeMarkers = append(*timeMarkers, s2)
}

如果你确实需要并发执行,那么必须使用适当的同步机制来协调对共享数据的访问。

回到顶部