
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 我想在里面添加一些东西, 但是一直报错, 怎样才能顺利添加进去呢?
1 2kCS5c0b0ITXE5k2 2020-11-02 22:58:43 +08:00 报啥错啊 |
2 Vibra OP @emeab 错误写在了代码中了 `panic: reflect: call of reflect.Value.Elem on slice Value` |
3 impl 2020-11-02 23:29:10 +08:00 Go 圣经没看过?少用 reflect 和 unsafe 这两个包 |
4 treblex 2020-11-02 23:34:46 +08:00 via iPhone 使用 .([]int) 推算类型,修改切片试试吧 |
5 Vibra OP @impl 主要是自己对 golang 不是很熟悉,一熟悉一下语法, 二是有点代码洁癖吧 reflect 节省了大量的重复代码 |
6 Vibra OP @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) } ``` |
7 mason961125 2020-11-02 23:46:56 +08:00 |
8 merin96 2020-11-03 06:10:06 +08:00 via iPhone 这玩意慢得很,小心使用 |
9 BBCCBB 2020-11-03 08:27:53 +08:00 这报错应该是 aValue := arrValue.Elem() 这一行的数据, arrValue := reflect.ValueOf(&tt).Elem().FieldByName("Arr") 你在这里已经调用过 Elem()了, 获取到的就是 slice 了, slice 没法再 elem()了. |
10 CEBBCAT 2020-11-03 09:12:26 +08:00 via Android @impl 少用又不是不能用,现在就是要解决用得不好的问题。就像人家在尝试使用 goto 解决跳出循环的问题时,旁人插一嘴 goto 是毒药,不能用,这不是搞笑呢吗? |
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) } ``` |
12 GopherDaily 2020-11-03 09:47:21 +08:00 @Vibra 对 |
14 dimlau 2020-11-03 12:11:40 +08:00 |
16 no1xsyzy 2020-11-03 15:16:20 +08:00 @impl 那我问你:你在 #3 说少用的目的是什么?对楼主的问题有何建树? 猜想的可能: 1. 你认为这个问题可以更优雅地实现,不需要 reflect,那你 #13 的回复就显得非常诡异。 2. 你说的话与主题根本无关 你要纠结自句,那 #10 把 “不能用” 改成 “少用” 不是一样的吗? 那咱重新再来一遍? 少用又不是不能用,现在就是要解决用得不好的问题。就像人家在尝试使用 goto 解决跳出循环的问题时,旁人插一嘴 goto 是毒药,少用,这不是搞笑呢吗? |
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) } ``` |
20 Glauben 2020-11-03 20:02:30 +08:00 楼上正解 |