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().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) } ``` |
7
mason961125 2020-11-02 23:46:56 +08:00 1
|
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
楼上正解
|