"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > CanSet() 및 구조체로 구조체 필드를 수정하기 위해 리플렉션을 사용하는 방법은 무엇입니까?

CanSet() 및 구조체로 구조체 필드를 수정하기 위해 리플렉션을 사용하는 방법은 무엇입니까?

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

How to Use Reflection to Modify Struct Fields with CanSet() and Structs?

리플렉션을 사용하여 구조체 필드 수정: CanSet() 및 구조체

리플렉션을 사용하여 구조체 필드를 수정할 때는 원칙을 이해하는 것이 중요합니다. 필드 접근성 및 수정 뒤에 있습니다.

CanSet() for Structs

예제에서 CanSet()이 구조체 필드에 대해 false를 반환하는 것을 발견했습니다. 이는 기본적으로 Go에서는 리플렉션을 사용하여 구조체의 내보내지 않은(비공개) 필드를 수정하는 것을 허용하지 않기 때문입니다. 이는 내부 구조체 상태의 우발적이거나 악의적인 수정을 방지하기 위한 보안 조치입니다.

문제 해결

리플렉션을 사용하여 구조체 필드의 값을 설정하려면 다음을 고려하세요. 단계:

  1. 값 수정: SetField() 함수를 호출할 때 포인터를 구조체 값 자체가 아니라 구조체입니다. 이를 통해 복사본이 아닌 실제 구조체를 수정할 수 있습니다.
  2. 포인터에 Value.Elem() 사용: 구조체에 포인터를 전달하는 경우 Reflect.ValueOf를 사용해야 합니다. (source).Elem()을 사용하여 뾰족한 구조체의 Reflect.Value를 얻습니다. 그러면 실제 구조체 값으로 이동합니다.
  3. 필드 액세스에 FieldByName 사용: 구조체의 모든 필드를 반복하는 대신 v.FieldByName(fieldName)을 사용하여 원하는 특정 필드에 액세스합니다. 수정합니다. 이렇게 하면 올바른 필드에 액세스할 수 있고 더 효율적입니다.

수정된 코드

다음은 문제를 해결하는 수정된 코드입니다.

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

이제 이 코드는 Entry 구조체의 Field1 값을 성공적으로 수정합니다.

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

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

Copyright© 2022 湘ICP备2022001581号-3