猿问

无法设置类型为接口的结构的字段{}

我一直在为反射包而苦苦挣扎。下面的代码符合我的预期:


package main


import (

  "reflect"

  "log"

)

type Car struct {

  Model string

}

type Person struct {

  Name string

  Cars []Car

}


func ModifyIt(parent interface{},fieldName string, val interface{}) {

  slice := reflect.ValueOf(parent).Elem()

  nth := slice.Index(0)

  //row := nth.Interface() // this line causes errors

  row := nth.Interface().(Person)

  elem := reflect.ValueOf(&row).Elem()

  field := elem.FieldByName(fieldName)

  log.Println(field.CanSet())


}


func main() {


  p := []Person{Person{Name:"john"}}

  c := []Car{Car{"corolla"},Car{"jetta"}}


  ModifyIt(&p,"Cars",&c)

}

row := nth.Interface().(Person)但是,如果我用替换该行row := nth.Interface(),即删除类型断言,则会收到错误:


恐慌:反映:在接口值上调用 reflect.Value.FieldByName on line "field := elem.FieldByName(fieldName)


在过去的几个小时里,我尝试了很多其他的事情,比如尝试reflect.TypeOf()对reflect.Indirect()其他一些变量做等等,但没有成功。

我的问题是,当结构被键入为接口时,我该如何设置结构的字段?

慕桂英3389331
浏览 94回答 2
2回答

HUWWW

尝试这个:func ModifyIt(slice interface{}, fieldName string, newVal interface{}) {    // Create a value for the slice.    v := reflect.ValueOf(slice)    // Get the first element of the slice.    e := v.Index(0)    // Get the field of the slice element that we want to set.    f := e.FieldByName(fieldName)    // Set the value!    f.Set(reflect.ValueOf(newVal))}像这样称呼它:p := []Person{Person{Name: "john"}}c := []Car{Car{"corolla"}, Car{"jetta"}}ModifyIt(p, "Cars", c)请注意,调用直接传递切片而不是使用指向切片的指针。不需要指针并增加了额外的复杂性。

暮色呼如

纯粹出于运气,我终于得到了一些工作。我拼凑了一堆随机阅读的东西,几乎没有韵律或理由。我什至尝试阅读 Golang 网站上的反射法则,但我认为我没有很好地理解它与为什么我不能将变量类型设置为interface{}. 总的来说,我还是不明白我做了什么。我在下面的解决方案中充斥着评论,表明我很困惑,并且对我是否正确或安全地做事缺乏信心。package mainimport (&nbsp; "reflect"&nbsp; "log")type Car struct {&nbsp; Model string}type Person struct {&nbsp; Name string&nbsp; Cars []Car}func ModifyIt(parent interface{},fieldName string, val interface{}) {&nbsp; log.Println(parent)&nbsp; slice := reflect.ValueOf(parent).Elem()&nbsp; nth := slice.Index(0)&nbsp; row := nth.Interface()&nbsp; log.Println(nth.CanSet()) // I can set this nth item&nbsp; // I think I have a to make a copy, don't fully understand why this is necessary&nbsp; newitem := reflect.New(reflect.ValueOf(row).Type())&nbsp; newelem := newitem.Elem()&nbsp; field := newelem.FieldByName(fieldName)&nbsp; // I need to copy the values over from the old nth row to this new item&nbsp; for c:=0; c<nth.NumField(); c++ {&nbsp; &nbsp; newelem.Field(c).Set(reflect.Indirect(nth.Field(c)))&nbsp; }&nbsp; // now I can finally set the field for some reason I don't understand&nbsp; field.Set(reflect.ValueOf(val).Elem())&nbsp; // now that newitem has new contents in the field object, I need to overwrite the nth item with new item&nbsp; // I don't know why I'm doing it, but I'll do it&nbsp; // I also don't fully understand why I have to use Indirect sometimes, and not other times...it seems interchangeable with ValueOf(something).Elem(), I'm confused....&nbsp; nth.Set(reflect.Indirect(newitem))}func main() {&nbsp; p := []Person{Person{Name:"john"}}&nbsp; c := []Car{Car{"corolla"},Car{"jetta"}}&nbsp; ModifyIt(&p,"Cars",&c)&nbsp; // now parent is up to date, although I have no idea how I got here.&nbsp; log.Println(p)}如果有人可以发布更好的答案来消除我的困惑,那就太好了。我一直很难学习 golang。
随时随地看视频慕课网APP

相关分类

Go
我要回答