reflect를 사용하여 struct 필드의 값을 어떻게 설정합니까?
reflect
패키지를 사용하여 구조체 필드로 작업하는 데 어려움을 겪고 있습니다. 특히 필드 값을 설정하는 방법을 찾지 못했습니다.
유형 t struct {fi int; fs 문자열} var rt = t {123, "jblow"} var i64 int64 = 456
필드 i의 이름 가져 오기-작동하는 것 같습니다
var field = reflect.TypeOf(r).Field(i).Name
필드 i의 값을 a) 인터페이스 {}, b) int-작동하는 것 같습니다.
var iface interface{} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
필드 i의 값 설정-시도해보기-패닉
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic : 반출되지 않은 필드를 사용하여 얻은 값을 사용하여 reflect.Value · SetInt
필드 이름 "id"및 "name"이 마음에 들지 않는다고 가정하여 "Id"및 "Name"으로 이름이 변경되었습니다.
a)이 가정이 맞습니까?
b) 맞다면 같은 파일 / 패키지에서 필요하지 않다고 생각했습니다.
필드 i의 설정 값-두 번 시도 (필드 이름이 대문자로 표시됨)-패닉
reflect.ValueOf(r).Field(i).SetInt( 465 )
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic : 주소를 지정할 수없는 값을 사용하는 reflect.Value · SetInt
@peterSO의 아래 지침은 철저하고 고품질입니다.
네. 이것은 작동합니다 :
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
그는 필드 이름을 내보낼 수 있어야한다고 문서화합니다 (대문자로 시작).
Go는 오픈 소스 코드 로 제공됩니다 . 리플렉션에 대해 배우는 좋은 방법은 핵심 Go 개발자가 리플렉션을 사용하는 방법을 확인하는 것입니다. 예를 들어 Go fmt 및 json 패키지가 있습니다. 패키지 문서에는 패키지 파일 제목 아래에 소스 코드 파일에 대한 링크가 있습니다.
Go json 패키지는 Go 구조에서 JSON을 마샬링하고 언 마샬링합니다.
다음은 struct
오류를 조심스럽게 피하면서 필드 값을 설정하는 단계별 예제입니다 .
Go reflect
패키지에는 CanAddr
기능이 있습니다.
func (v Value) CanAddr() bool
Addr로 값의 주소를 얻을 수있는 경우 CanAddr은 true를 반환합니다. 이러한 값을 주소 지정 가능이라고합니다. 값은 슬라이스의 요소, 주소 지정 가능한 배열의 요소, 주소 지정 가능한 구조체의 필드 또는 포인터 역 참조의 결과 인 경우 주소를 지정할 수 있습니다. CanAddr이 false를 반환하면 Addr을 호출하면 패닉이 발생합니다.
이동의 reflect
패키지는이 CanSet
경우, 기능, true
즉 의미 CanAddr
도입니다 true
.
func (v Value) CanSet() bool
CanSet은 v 값을 변경할 수있는 경우 true를 반환합니다. 값은 주소 지정이 가능하고 내 보내지 않은 구조체 필드를 사용하여 얻지 못한 경우에만 변경할 수 있습니다. CanSet이 false를 반환하면 Set 또는 유형별 setter (예 : SetBool, SetInt64)를 호출하면 패닉이 발생합니다.
우리 Set
는 struct
현장에서 할 수 있는지 확인해야 합니다. 예를 들면
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
// N at start
fmt.Println(n.N)
// pointer to struct - addressable
ps := reflect.ValueOf(&n)
// struct
s := ps.Elem()
if s.Kind() == reflect.Struct {
// exported field
f := s.FieldByName("N")
if f.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if f.CanSet() {
// change value of N
if f.Kind() == reflect.Int {
x := int64(7)
if !f.OverflowInt(x) {
f.SetInt(x)
}
}
}
}
}
// N at end
fmt.Println(n.N)
}
Output:
42
7
If we can be certain that all the error checks are unnecessary, the example simplifies to,
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
fmt.Println(n.N)
reflect.ValueOf(&n).Elem().FieldByName("N").SetInt(7)
fmt.Println(n.N)
}
This seems to work:
package main
import (
"fmt"
"reflect"
)
type Foo struct {
Number int
Text string
}
func main() {
foo := Foo{123, "Hello"}
fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
reflect.ValueOf(&foo).Elem().Field(0).SetInt(321)
fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
}
Prints:
123
321
참고URL : https://stackoverflow.com/questions/6395076/using-reflect-how-do-you-set-the-value-of-a-struct-field
'Programing' 카테고리의 다른 글
데이터베이스 내의 테이블 열에서 하나의 값을 검색합니다. (0) | 2020.09.03 |
---|---|
SSD 드라이브 및 Visual Studio IDE. (0) | 2020.09.03 |
자체 템플릿으로 기본 제공 암호 재설정 / 변경보기를 사용하는 방법 (0) | 2020.09.03 |
C에서 문자열을 어떻게 소문자로 지정합니까? (0) | 2020.09.03 |
TypeAdapter를 사용하는 개체의 하나의 변수에 대한 Gson 사용자 지정 세랄 라이저 (0) | 2020.09.03 |