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