developer tip

이름으로 구조체 속성에 액세스

copycodes 2020. 12. 30. 08:18
반응형

이름으로 구조체 속성에 액세스


다음은 작동하지 않는 간단한 go 프로그램입니다.

package main
import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getProperty(&v, "X"))
}

func getProperty(v *Vertex, property string) (string) {
    return v[property]
}

오류:

prog.go : 18 : 잘못된 연산 : v [property] (* Vertex 유형의 인덱스)

내가 원하는 것은 이름을 사용하여 Vertex X 속성에 액세스하는 것입니다. 내가 v.X하면 작동하지만 작동 v["X"]하지 않습니다.

누군가이 작업을 수행하는 방법을 말해 줄 수 있습니까?


대부분의 코드에는 이런 종류의 동적 조회가 필요하지 않습니다. 직접 액세스에 비해 비효율적입니다 (컴파일러는 Vertex 구조에서 X 필드의 오프셋을 알고 있으며 vX를 단일 기계 명령어로 컴파일 할 수있는 반면 동적 조회에는 일종의 해시 테이블 구현 또는 이와 유사한 것이 필요합니다). 또한 정적 유형 지정을 금지합니다. 컴파일러는 알 수없는 필드에 동적으로 액세스하려고하지 않는지 확인할 방법이 없으며 결과 유형이 무엇인지 알 수 없습니다.

하지만 ...이 언어는 드물게 필요한 경우에 반영 모듈을 제공합니다 .

package main

import "fmt"
import "reflect"

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(getField(&v, "X"))
}

func getField(v *Vertex, field string) int {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return int(f.Int())
}

여기에는 오류 검사가 없으므로 존재하지 않는 필드를 요청하거나 필드가 int 유형이 아닌 경우 패닉이 발생합니다. 자세한 내용 은 reflect 문서를 확인 하세요.


이제 구조체 값 또는 포인터에 대한 필드를 가져 오거나 설정할 수 있는 프로젝트 oleiade / reflections 가 있습니다. 패키지
사용이 덜 까다로워집니다.reflect

s := MyStruct {
    FirstField: "first value",
    SecondField: 2,
    ThirdField: "third value",
}

fieldsToExtract := []string{"FirstField", "ThirdField"}

for _, fieldName := range fieldsToExtract {
    value, err := reflections.GetField(s, fieldName)
    DoWhatEverWithThatValue(value)
}


// In order to be able to set the structure's values,
// a pointer to it has to be passed to it.
_ := reflections.SetField(&s, "FirstField", "new value")

// If you try to set a field's value using the wrong type,
// an error will be returned
err := reflection.SetField(&s, "FirstField", 123)  // err != nil

참조 URL : https://stackoverflow.com/questions/18930910/access-struct-property-by-name

반응형