首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用反射SetString

使用反射SetString
EN

Stack Overflow用户
提问于 2017-05-30 14:48:04
回答 1查看 1.8K关注 0票数 2

我有一个像这样的结构:

代码语言:javascript
复制
type ProductionInfo struct {
    StructA []Entry
}

type Entry struct {
    Field1 string
    Field2 int
}

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

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

代码如下:

代码语言:javascript
复制
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")
}
EN

回答 1

Stack Overflow用户

发布于 2017-05-30 15:00:30

多个错误。让我们遍历它们。

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

代码语言:javascript
复制
SetField(source.StructA[0], "Field1", "NEW_VALUE")

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

代码语言:javascript
复制
SetField(&source.StructA[0], "Field1", "NEW_VALUE")

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

代码语言:javascript
复制
v := reflect.ValueOf(source).Elem()

现在它起作用了。修改后的代码:

代码语言:javascript
复制
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上试用):

代码语言:javascript
复制
Before:  {A 2}
true
After:  {NEW_VALUE 2}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44255344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档