duanba8070 2018-10-04 04:18
浏览 50
已采纳

混淆在Go中使用指针

I have my sample code like below.

type Apple struct {
    Color string
}
//In this way, the code runs just fine.
func main(){
        var test = 6
        TestTest(&test)
        fmt.Println(test)
        a := Apple{"red"}
        Eat(&a)
        fmt.Println(a.Color)
}


    func TestTest(num *int) {
        *num = *num + 2
    }
    func Eat(a *Apple) {
        a.Color = "green"
    }

the question is, why do I have to put a star(*) before a num variable but not for a.Color? If I do so to a.Color, it says

invalid indirect of a.Color (type string)

or if I remove a star(*) from num, it says

invalid operation: num + 2 (mismatched types *int and int)

that makes me confused, can someone explain why?

  • 写回答

2条回答 默认 最新

  • drhgzx4727 2018-10-04 04:21
    关注

    These are two different cases:

    Case1

    num is a pointer to int, So you need to add the integer value to the value stored at address pointed by num. Hence you are dereferencing the num pointer to get the value stored inside it as:

    func TestTest(num *int) {
        *num = *num + 2 // dereference the pointer to get the value.
    }
    

    Case2

    you are assigning a string value to Color field of Apple struct which is not a pointer. But you are using the pointer to the struct not to the field. That's why you are able to assign a value like this:

    func Eat(a *Apple) { // a is the pointer to struct.
        a.Color = "green"
    }
    

    Now if you want to generate the same error which is you are getting in first case, create a pointer type Color field inside the struct as:

    type Apple struct {
        Color *string // this is the pointer value which will throw the same error in your current implementation.
    }
    

    Error code on Go playground when trying to assign a pointer type value to a non-pointer variable when using struct.

    Solution

    To set the value in case you are using pointer field in a struct use reflection as:

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    //I have my sample code like this.
    
    type Apple struct {
        Color *string
    }
    
    //In this way, the code runs just fine.
    func main() {
        var test = 6
        TestTest(&test)
        fmt.Println(test)
        point := "red"
        a := Apple{&point}
        Eat(&a)
        fmt.Println(a.Color)
    }
    
    func TestTest(num *int) {
        *num = *num + 2
    }
    func Eat(a *Apple) {
        str := "green"
        r := reflect.ValueOf(a)
        elm := r.Elem().FieldByName("Color")
        elm.Set(reflect.ValueOf(&str))
        fmt.Printf("%+v", (*a).Color)
    }
    

    Playground Example

    One more thing to notice is the value of reflection is actually reflect.Ptr so what we can do is we can loop over the struct fields to get the value and then use reflect.Indirect to get the value of the pointer type color field.

    func Eat(a *Apple) {
        str := "green"
        r := reflect.ValueOf(a).Elem()
        elm := r.FieldByName("Color")
        elm.Set(reflect.ValueOf(&str))
        fmt.Printf("%+v
    ", (*a).Color)
        for i := 0; i < r.NumField(); i++ {
            valueField := r.Field(i)
            fmt.Println(reflect.Indirect(valueField))
        }
        // or use FieldByName to get the value of a field.
        st := "Color"
        fmt.Println(reflect.Indirect(reflect.ValueOf(a).Elem().FieldByName(st)))
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?