请教一个 golang 中 reflect 的问题, 琢磨了一下午了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Vibra
V2EX    程序员

请教一个 golang 中 reflect 的问题, 琢磨了一下午了

  •  
  •   Vibra 2020-11-02 22:54:05 +08:00 2823 次点击
    这是一个创建于 1891 天前的主题,其中的信息可能已经有所发展或是发生改变。
    package main import ( "fmt" "reflect" ) type arrT struct { Arr []int } func main() { tt := arrT{ Arr: []int{1, 2}, } arrValue := reflect.ValueOf(&tt).Elem().FieldByName("Arr") fmt.Printf("%v, %T\n", arrValue, arrValue) aValue := arrValue.Elem() aValue.Set(reflect.Append(aValue, reflect.ValueOf(80))) // panic: reflect: call of reflect.Value.Elem on slice Value fmt.Println("Slice after appending data:", tt) } 

    如代码所示

    一个结构体中有一个 split 我想在里面添加一些东西, 但是一直报错, 怎样才能顺利添加进去呢?

    21 条回复    2020-11-03 22:24:27 +08:00
    2kCS5c0b0ITXE5k2
        1
    2kCS5c0b0ITXE5k2  
       2020-11-02 22:58:43 +08:00
    报啥错啊
    Vibra
        2
    Vibra  
    OP
       2020-11-02 23:09:20 +08:00
    @emeab 错误写在了代码中了 `panic: reflect: call of reflect.Value.Elem on slice Value`
    impl
        3
    impl  
       2020-11-02 23:29:10 +08:00
    Go 圣经没看过?少用 reflect 和 unsafe 这两个包
    treblex
        4
    treblex  
       2020-11-02 23:34:46 +08:00 via iPhone
    使用 .([]int) 推算类型,修改切片试试吧
    Vibra
        5
    Vibra  
    OP
       2020-11-02 23:41:47 +08:00
    @impl 主要是自己对 golang 不是很熟悉,一熟悉一下语法, 二是有点代码洁癖吧 reflect 节省了大量的重复代码
    Vibra
        6
    Vibra  
    OP
       2020-11-02 23:44:22 +08:00
    @suke971219 这个修改不到原本的切片呀, 我现在已经修改好了, 谢谢. 代码附上供大家参考
    ```golang

    func main() {
    tt := arrT{
    Arr: []int{1, 2},
    }

    arrValue := reflect.ValueOf(&tt).Elem().FieldBName("Arr")
    fmt.Printf("%v, %T\n", arrValue, arrValue)

    arrValue.Set(reflect.Append(arrValue, reflect.ValueOf(80)))

    fmt.Println("Slice after appending data:", tt.Arr)
    }
    ```
    mason961125
        7
    mason961125  
       2020-11-02 23:46:56 +08:00   1
    merin96
        8
    merin96  
       2020-11-03 06:10:06 +08:00 via iPhone
    这玩意慢得很,小心使用
    BBCCBB
        9
    BBCCBB  
       2020-11-03 08:27:53 +08:00
    这报错应该是 aValue := arrValue.Elem() 这一行的数据,

    arrValue := reflect.ValueOf(&tt).Elem().FieldByName("Arr") 你在这里已经调用过 Elem()了, 获取到的就是 slice 了, slice 没法再 elem()了.
    CEBBCAT
        10
    CEBBCAT  
       2020-11-03 09:12:26 +08:00 via Android
    @impl 少用又不是不能用,现在就是要解决用得不好的问题。就像人家在尝试使用 goto 解决跳出循环的问题时,旁人插一嘴 goto 是毒药,不能用,这不是搞笑呢吗?
    useben
        11
    useben  
       2020-11-03 09:36:44 +08:00
    一堆人都不知道说什么...

    reflect.ValueOf(&tt).Elem() 这里已经对对象指针相当于解引用了, 已经拿到对象值信息, aValue := arrValue.Elem() 这里没必要再用 Elem() , 修改为一下即可

    ```go
    package main

    import (
    "fmt"
    "reflect"
    )

    type arrT struct {
    Arr []int
    }


    func main() {
    tt := arrT{
    Arr: []int{1, 2},
    }

    arrValue := reflect.ValueOf(&tt).Elem().FieldByName("Arr")
    fmt.Printf("%v, %T\n", arrValue, arrValue)

    aValue := arrValue
    aValue.Set(reflect.Append(aValue, reflect.ValueOf(80)))

    fmt.Println("Slice after appending data:", tt)
    }
    ```
    GopherDaily
        12
    GopherDaily  
       2020-11-03 09:47:21 +08:00
    @Vibra
    impl
        13
    impl  
       2020-11-03 10:31:03 +08:00
    @CEBBCAT 我说不能用了吗?要不回去学校找体育老师教你语文?
    dimlau
        14
    dimlau  
       2020-11-03 12:11:40 +08:00
    @impl

    1 、顶楼作者没说要多用 reflect 和 unsafe 这两个包,只是在使用时遇到了具体问题希望探讨。
    ---> 而回复说 Go 圣经主张少用;

    2 、 @CEBBCAT 反驳说「少用又不是不能用」,意思是会尽量少用但是在用的时候遇到问题还是要解决啊。
    ---> 而回复说「我说不能用了吗?」。

    似乎这两次互动都是(不知是否故意地)理解错了别人的意思,为什么还要让别人回学校学语文呢?
    impl
        15
    impl  
       2020-11-03 12:38:25 +08:00 via Android
    @dimlau 看看他举的 goto 例子
    no1xsyzy
        16
    no1xsyzy  
       2020-11-03 15:16:20 +08:00
    @impl 那我问你:你在 #3 说少用的目的是什么?对楼主的问题有何建树?
    猜想的可能:
    1. 你认为这个问题可以更优雅地实现,不需要 reflect,那你 #13 的回复就显得非常诡异。
    2. 你说的话与主题根本无关

    你要纠结自句,那 #10 把 “不能用” 改成 “少用” 不是一样的吗?
    那咱重新再来一遍?

    少用又不是不能用,现在就是要解决用得不好的问题。就像人家在尝试使用 goto 解决跳出循环的问题时,旁人插一嘴 goto 是毒药,少用,这不是搞笑呢吗?
    no1xsyzy
        17
    no1xsyzy  
       2020-11-03 15:16:48 +08:00
    @no1xsyzy 自句 -> 字句
    impl
        18
    impl  
       2020-11-03 15:59:33 +08:00
    @no1xsyzy 那你的建议就是一个 go 初学者浪费一个下午时间琢磨怎么用 reflect 这个包咯?
    lxz6597863
        19
    lxz6597863  
       2020-11-03 18:18:08 +08:00
    ```go
    package main

    import (
    "fmt"
    "reflect"
    )

    type arrT struct {
    Arr []int
    }

    func main() {
    tt := arrT{
    Arr: []int{1, 2},
    }

    arrValue := reflect.ValueOf(&tt).Elem().FieldByName("Arr")
    fmt.Printf("%v, %T\n", arrValue, arrValue)

    arrValue.Set(reflect.Append(arrValue, reflect.ValueOf(80)))
    // panic: reflect: call of reflect.Value.Elem on slice Value

    fmt.Println("Slice after appending data:", tt)
    }
    ```
    Glauben
        20
    Glauben  
       2020-11-03 20:02:30 +08:00
    楼上正解
    no1xsyzy
        21
    no1xsyzy  
       2020-11-03 22:24:27 +08:00
    @impl 我感觉你纯粹是不会说话,或者心态崩了
    “我建议先考虑不用 reflect 解决问题。另外,楼主可以把原本的问题问出来,以避免这是个潜在的 X-Y 问题”
    这是否正确表达了你的意图?同时,这样一段话又能显得说话人温和谦虚且博学。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5700 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 06:27 PVG 14:27 LAX 22:27 JFK 01:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86