"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como superar SetCan() sempre retornando falso ao definir valores de campos estruturais usando reflexão?

Como superar SetCan() sempre retornando falso ao definir valores de campos estruturais usando reflexão?

Publicado em 2024-11-09
Navegar:821

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

Explorando Reflection com SetString para Structs

Reflection fornece ferramentas poderosas para manipular estruturas Go dinamicamente. Neste exemplo, encontramos um problema comum ao tentar definir o valor de um campo struct usando reflexão: CanSet() sempre retorna falso. Esse obstáculo impede modificações de campo, deixando-nos em um dilema.

Identificando as armadilhas

O snippet de código fornecido destaca dois erros fundamentais:

  1. Passando um valor em vez de um ponteiro: Estruturas por valor não podem ser modificadas por reflexão. Em vez disso, devemos passar um ponteiro para a estrutura, garantindo que quaisquer alterações sejam aplicadas ao objeto real.
  2. Segmentação incorreta do elemento: O código inicialmente opera em toda a estrutura ProductionInfo, e não na Entrada específica cujo valor Field1 precisa ser alterado. Para corrigir isso, precisamos nos concentrar no elemento Entry desejado.

Resolvendo os problemas

Depois de resolver essas armadilhas, podemos refinar nosso código:

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

Na função SetField() modificada, nós:

  1. Usamos Elem() para navegar até o valor do objeto apontado, garantindo que operamos na estrutura real.
  2. Use FieldByName() para acessar o campo específico que queremos modificar.

Codifique em Action

Com essas modificações, o código agora atualiza com sucesso o valor do Campo1:

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

Saída:

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

O resultado mostra a modificação bem-sucedida de Field1 na estrutura Entry.

Declaração de lançamento Este artigo foi reimpresso em: 1729662680 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3