"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 리플렉션을 사용하여 구조체 필드 값을 설정할 때 SetCan()이 항상 False를 반환하는 문제를 해결하는 방법은 무엇입니까?

리플렉션을 사용하여 구조체 필드 값을 설정할 때 SetCan()이 항상 False를 반환하는 문제를 해결하는 방법은 무엇입니까?

2024-11-09에 게시됨
검색:223

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

구조체용 SetString을 사용하여 Reflection 탐색

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}

결과는 Entry 구조 내에서 Field1이 성공적으로 수정되었음을 보여줍니다.

릴리스 선언문 이 글은 1729662680에서 재인쇄되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3