gpt4 book ai didi

string - 使用反射 SetString

转载 作者:IT王子 更新时间:2023-10-29 02:11:49 26 4
gpt4 key购买 nike

我有一个这样的结构:

type ProductionInfo struct {
StructA []Entry
}

type Entry struct {
Field1 string
Field2 int
}

我想使用反射更改 Field1 的值,但反射对象总是返回 CanSet() = false。我能做些什么?请参阅 Playground 示例。

https://play.golang.org/p/eM_KHC3kQ5

代码如下:

func SetField(source interface{}, fieldName string, fieldValue string) {
v := reflect.ValueOf(source)
tt := reflect.TypeOf(source)

for k := 0; k < tt.NumField(); k++ {
fieldValue := reflect.ValueOf(v.Field(k))

fmt.Println(fieldValue.CanSet())
if fieldValue.CanSet() {
fieldValue.SetString(fieldValue.String())
}
}
}

func main() {
source := ProductionInfo{}
source.StructA = append(source.StructA, Entry{Field1: "A", Field2: 2})

SetField(source, "Field1", "NEW_VALUE")
}

最佳答案

多个错误。让我们迭代它们。

首先,您传递的是 ProductionInfo 的值,而不是要修改其字段的 Entry 的值,因此首先将其更改为:

SetField(source.StructA[0], "Field1", "NEW_VALUE")

接下来,您要传递一个(非指针)值。您不能使用反射修改非指针结构的字段,因为那样只会修改将被丢弃的副本。为了避免这种情况(以及进一步的混淆),这是不允许的(CanSet() 返回 false)。所以你必须传递一个指向结构的指针:

SetField(&source.StructA[0], "Field1", "NEW_VALUE")

现在在 SetField() 中,reflect.ValueOf(source) 将描述传递的指针。您可以使用 Value.Elem()导航到 reflect.Value指向对象的(结构值):

v := reflect.ValueOf(source).Elem()

现在可以了。修改代码:

func SetField(source interface{}, fieldName string, fieldValue string) {
v := reflect.ValueOf(source).Elem()

fmt.Println(v.FieldByName(fieldName).CanSet())

if v.FieldByName(fieldName).CanSet() {
v.FieldByName(fieldName).SetString(fieldValue)
}
}

func main() {
source := ProductionInfo{}
source.StructA = append(source.StructA, Entry{Field1: "A", Field2: 2})

fmt.Println("Before: ", source.StructA[0])
SetField(&source.StructA[0], "Field1", "NEW_VALUE")
fmt.Println("After: ", source.StructA[0])
}

输出(在 Go Playground 上尝试):

Before:  {A 2}
true
After: {NEW_VALUE 2}

关于string - 使用反射 SetString,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44255344/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com