«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как обойти SetCan(), всегда возвращающую значение False при установке значений полей структуры с использованием отражения?

Как обойти SetCan(), всегда возвращающую значение False при установке значений полей структуры с использованием отражения?

Опубликовано 9 ноября 2024 г.
Просматривать:270

How to Overcome SetCan() Always Returning False When Setting Struct Field Values Using Reflection?

Изучение отражения с помощью SetString для структур

Reflection предоставляет мощные инструменты для динамического управления структурами Go. В этом примере мы сталкиваемся с распространенной проблемой при попытке установить значение поля структуры с помощью отражения: CanSet() всегда возвращает false. Это препятствие препятствует модификации полей, ставя нас в затруднительное положение.

Выявление ловушек

Приведенный фрагмент кода подчеркивает две фундаментальные ошибки:

  1. Передача значения вместо указателя: Структуры по значению не могут быть изменены посредством отражения. Вместо этого мы должны передать указатель на структуру, гарантируя, что любые изменения будут применены к фактическому объекту.
  2. Неверное нацеливание на элемент: Первоначально код работает со всей структурой ProductionInfo, а не со всей структурой ProductionInfo. конкретная запись, значение Field1 которой необходимо изменить. Чтобы исправить это, нам нужно сосредоточиться на желаемом элементе Entry.

Решение проблем

После устранения этих ошибок мы можем усовершенствовать наш код:

func SetField(source interface{}, fieldName string, fieldValue string) {
    v := reflect.ValueOf(source).Elem() // Obtain the value of the pointed object
    fmt.Println(v.FieldByName(fieldName).CanSet())
    if v.FieldByName(fieldName).CanSet() {
        v.FieldByName(fieldName).SetString(fieldValue)
    }
}

В модифицированной функции SetField() мы:

  1. Используем Elem() для перехода к значению указанного объекта, гарантируя, что мы работаем с фактической структурой.
  2. Используйте FieldByName() для доступа к определенному полю, которое мы хотим изменить.

Код в действии

Благодаря этим изменениям код теперь успешно работает обновляет значение Field1:

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

Вывод:

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

Результат демонстрирует успешное изменение поля Field1 в структуре Entry.

Заявление о выпуске Эта статья перепечатана по адресу: 1729662680. В случае каких-либо нарушений, пожалуйста, свяжитесь с [email protected], чтобы удалить ее.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3