登录
首页 >  Golang >  Go问答

为何在函数中可以修改切片的值,而在 for 循环中却不能?

来源:stackoverflow

时间:2024-03-04 23:27:24 327浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《为何在函数中可以修改切片的值,而在 for 循环中却不能?》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

我需要在接收切片指针的函数中将每个分数更改为其他值,我可以通过分配来更改值,但如果我在 for 循环中执行此操作,则不会发生任何变化。这是为什么?

package main

import (
    "fmt"
    "sync"
    "time"
)

type testtype struct {
    id    int
    score float64
}

func worker(index int, wg *sync.waitgroup, listscores *[][]testtype) {
    defer wg.done()
    time.sleep(1000 * time.millisecond)

    // it works by assigning.
    (*listscores)[index] = []testtype{{index + 1, 2.22},
        {index + 1, 2.22},
        {index + 1, 2.22},}
    // it doesn't work in a for loop.
    //for _, score := range (*listscores)[index] {
    //  score.score = 2.22
    //}
}

func main() {
    scoreslist := [][]testtype{
        {{1, 0.0},
            {1, 0.0},
            {1, 0.0},},
        {{2, 0.0},
            {2, 0.0},
            {2, 0.0},
        },}

    fmt.println(scoreslist)

    var wg sync.waitgroup
    for i, _ := range scoreslist {
        wg.add(1)
        go worker(i, &wg, &scoreslist)
    }
    wg.wait()

    fmt.println(scoreslist)
}

通过为其分配新的整个切片,可以将分数更改为 2.22:

[[{1 0} {1 0} {1 0}] [{2 0} {2 0} {2 0}]]
[[{1 2.22} {1 2.22} {1 2.22}] [{2 2.22} {2 2.22} {2 2.22}]]

但是如果我像评论中那样在 for 循环中执行此操作,则输出如下:

[[{1 0} {1 0} {1 0}] [{2 0} {2 0} {2 0}]]
[[{1 0} {1 0} {1 0}] [{2 0} {2 0} {2 0}]]

解决方案


因为 range 给你两个元素:

  • 索引
  • 如果迭代切片,则为元素的副本

不使用线程,代码可以改为如下:

package main

import (
    "fmt"
)

type testtype struct {
    id    int
    score float64
}

func main() {
    scoreslist := [][]testtype{
        {{1, 0.0}, {1, 0.0}, {1, 0.0}},
        {{2, 0.0}, {2, 0.0}, {2, 0.0}}}
    fmt.println(scoreslist)
    for i := range scoreslist {
        scoreslist[i] = []testtype{{i + 1, 2.22},
            {i + 1, 2.22},
            {i + 1, 2.22}}
    }
    fmt.println(scoreslist)
}

如果你想使用线程,那么你可以使用以下线程:

package main

import (
    "fmt"
    "sync"
    "time"
)

type TestType struct {
    id    int
    score float64
}

func worker(index int, wg *sync.WaitGroup, listScores *[][]TestType) {
    defer wg.Done()
    time.Sleep(1000 * time.Millisecond)

    for i := range (*listScores)[index] {
        (*listScores)[index][i].score = 2.22
    }
}

func main() {
    scoresList := [][]TestType{
        {{1, 0.0},
            {1, 0.0},
            {1, 0.0}},
        {{2, 0.0},
            {2, 0.0},
            {2, 0.0},
        }}

    fmt.Println(scoresList)

    var wg sync.WaitGroup
    for i, _ := range scoresList {
        wg.Add(1)
        go worker(i, &wg, &scoresList)
    }
    wg.Wait()

    fmt.Println(scoresList)
}

到这里,我们也就讲完了《为何在函数中可以修改切片的值,而在 for 循环中却不能?》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>