字符串切片的范围不一致
Posted
技术标签:
【中文标题】字符串切片的范围不一致【英文标题】:Range over string slice is inconsistent 【发布时间】:2018-02-07 01:39:17 【问题描述】:这段代码:
import "fmt"
import "time"
func main()
string_slice:=[]string"a","b","c"
for _,s:=range string_slice
go func()
time.Sleep(1*time.Second)
fmt.Println(s)
()
time.Sleep(3*time.Second)
产生输出“c c c”,而这段代码:
import "fmt"
func main()
string_slice:=[]string"a","b","c"
for _,s:=range string_slice
s="asd"
fmt.Println(s)
fmt.Println(string_slice)
产生输出“[a b c]”
第一个建议 for range 迭代引用(它不应该),第二个建议它迭代值的副本(它应该)。
为什么第一个不产生输出“a b c”?
【问题讨论】:
第二个有什么意义?在打印"asd"
3 次后,您只是在打印整个切片。 play.golang.org/p/rNEGrgS3AT
github.com/golang/go/wiki/…
golang.org/doc/faq#closures_and_goroutines
【参考方案1】:
当使用 goroutine 时,你必须假设它会并行运行。所以在这种情况下可能会出现 'c c c' as too 'b b b' 或 'a a a'
在此代码运行 3 次时:
for _,s:=range string_slice \\run t0, t1, t2
您将发送运行 3 次此代码:
go func()
fmt.Println(s)
()//send in t0, t1, t2
因此,例如,func() 可能会在 t2 开始运行。在这种情况下,结果将是 'c c c',因为 s 等于最新值 (string_slice[2])。
解决方法是通过 func params 复制值:
for _, s := range string_slice
go func(x string)
time.Sleep(1*time.Second)
fmt.Println(x)
(s)
或者每次迭代都创造新的价值
//creating new value per iteration
for i := range string_slice
s := string_slice[i]
go func()
time.Sleep(1*time.Second)
fmt.Println(s)
()
查看在https://play.golang.org/p/uRD6Qy6xSw工作
【讨论】:
以上是关于字符串切片的范围不一致的主要内容,如果未能解决你的问题,请参考以下文章
当 j 有时为 0 时,如何避免不一致的 s[i:-j] 切片行为?