亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無法設置類型為接口的結構的字段{}

無法設置類型為接口的結構的字段{}

Go
慕桂英3389331 2023-03-29 15:34:11
我一直在為反射包而苦苦掙扎。下面的代碼符合我的預期:package mainimport (  "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()其他一些變量做等等,但沒有成功。我的問題是,當結構被鍵入為接口時,我該如何設置結構的字段?
查看完整描述

2 回答

?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

嘗試這個:


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)

請注意,調用直接傳遞切片而不是使用指向切片的指針。不需要指針并增加了額外的復雜性。



查看完整回答
反對 回復 2023-03-29
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

純粹出于運氣,我終于得到了一些工作。


我拼湊了一堆隨機閱讀的東西,幾乎沒有韻律或理由。我什至嘗試閱讀 Golang 網站上的反射法則,但我認為我沒有很好地理解它與為什么我不能將變量類型設置為interface{}. 總的來說,我還是不明白我做了什么。


我在下面的解決方案中充斥著評論,表明我很困惑,并且對我是否正確或安全地做事缺乏信心。


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{}) {

  log.Println(parent)

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

  nth := slice.Index(0)

  row := nth.Interface()

  log.Println(nth.CanSet()) // I can set this nth item


  // I think I have a to make a copy, don't fully understand why this is necessary

  newitem := reflect.New(reflect.ValueOf(row).Type())

  newelem := newitem.Elem()

  field := newelem.FieldByName(fieldName)


  // I need to copy the values over from the old nth row to this new item

  for c:=0; c<nth.NumField(); c++ {

    newelem.Field(c).Set(reflect.Indirect(nth.Field(c)))

  }


  // now I can finally set the field for some reason I don't understand

  field.Set(reflect.ValueOf(val).Elem())


  // now that newitem has new contents in the field object, I need to overwrite the nth item with new item

  // I don't know why I'm doing it, but I'll do it

  // 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....

  nth.Set(reflect.Indirect(newitem))


}


func main() {


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

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


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

  // now parent is up to date, although I have no idea how I got here.

  log.Println(p)

}

如果有人可以發布更好的答案來消除我的困惑,那就太好了。我一直很難學習 golang。


查看完整回答
反對 回復 2023-03-29
  • 2 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號