【问题标题】:How to pass slice of struct as pointer to a function and modify it?如何将结构切片作为指向函数的指针传递并修改它?
【发布时间】:2017-12-18 19:48:21
【问题描述】:

我有一个struct []student,我想用函数修改它的内容。

type student struct {
    name string
    age int
}

students := []student{
    {"Doraemon", 30},
    {"King Kong", 25},
}

因此,我决定将其作为指针传递。我可以知道如何将切片作为对函数的引用传递吗?

func addAge (s *[]student) error { //this code has error
    //everyone add 2 years old
    for i, e := range *s {
        s[i].age = s[i].age + 2
    }
    //make the first student much older
    s[0].age = s[0].age + 5
    return nil
}

我一直在玩Go Playground,但它给了很多抱怨,比如

cannot range over s (type *[]student)
invalid operation: s[i] (type *[]student does not support indexing)
invalid indirect of s
...

如何精确地将slice of struct 的引用传递给函数?如何range结构切片?以及如何更改结构的值(修改 THE slice 中的相同结构)?

我在玩s *[]studentrange *ss []students *[]*student 时不断出错......很难让它正确......

抱歉我的新手问题,还在学习 GO...努力中

【问题讨论】:

  • 请向我们展示您的exact错误的exact code。当您有不同的、相互冲突的错误消息时,很难告诉您如何改进您的代码。
  • 另外,您不需要传递指向切片的指针——切片已经通过引用传递。
  • 必须阅读,blog.golang.org/slices。切片是安静特别的东西。

标签: go


【解决方案1】:

切片是通过引用传递的,因此只要您修改现有切片内容,就不应显式传递指针。

package main

import (
    "fmt"
)

type student struct {
    name string
    age int
}

func main() {
    students := []student{
        {"Doraemon", 30},
        {"King Kong", 25},
    }

    err := addAge (students)

    fmt.Println(students)
    if err != nil {
        fmt.Println("error")
    }
}

func addAge (s []student) error {
    for i, _ := range s {
        s[i].age = 3
    }
    return nil
}

现在,对于您的 addAdditinalStudent 函数,您应该实际使用 append 函数。另外,请记住

...,因为切片头总是通过调用来更新 append,调用后需要保存返回的 slice。实际上, 编译器不会让您在不保存结果的情况下调用 append 。 Slices#append

// add student
students = append(students, student{"Test", 33})

Go Playground

【讨论】:

    【解决方案2】:

    在 Go 中,您可以通过值 ([]student) 或引用 ([]*student) 传递项目。当您想对 struct{} 的值进行操作时,您应该将其传递给带有 reference(指针)的函数。

    所以你可以这样做:

    type student struct {
        name string
        age int
    }
    
    func addTwoYearsToAll(students []*student){
      for _, s := range students {
            s.age += 2
         }
    }
    

    通过这种方式,您可以使用在附加到切片时构建的完全相同的项目。 Playground example.

    也可以看看Are Golang function parameter passed as copy-on-write?

    【讨论】:

    • 这无效,s 是一个整数。如果s*student,则不要取消引用s.age,因为age 不是指针。
    猜你喜欢
    • 2013-09-02
    • 2014-03-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2021-07-17
    相关资源
    最近更新 更多