Go1.15에서 온 리플렉스 포장의 행위 차이에 대해
개요
Go1.15에서reflect 패키지의 일부 행동을 바꿨습니다.여기서, Go1.14 이전에 조작된 코드는 패닉일 수 있습니다.
패닉은 비공개 구조를 포함하고 해당 구조체를 콜하는 방법을 사용하는 경우
필기를 발행하는 기술
Go1.15의 발행 노트에 따르면reflect 포장에 대해 다음과 같은 기술이 있다.
Package reflect now disallows accessing methods of all non-exported fields, whereas previously it allowed accessing those of non-exported, embedded fields. Code that relies on the previous behavior should be updated to instead access the corresponding promoted method of the enclosing variable.
샘플 코드
샘플 코드는 다음과 같습니다.두 개의 구조를 정의했다.
unexportedStruct
Print만 사용할 수 있습니다.R
에는 상기 unexported Struct가 박혀 있다.package main
import (
"fmt"
"reflect"
)
type unexportedStruct struct{}
func (s unexportedStruct) Print() {
fmt.Println("Print!")
}
type R struct {
unexportedStruct
}
func main() {
v := reflect.ValueOf(R{})
fmt.Printf("NumMethod=%d\n", v.Field(0).NumMethod())
method := v.Field(0).Method(0)
fmt.Printf("Method=%v\n", method)
method.Call(nil)
}
Go1.14와 고1.15의 차이
다음은 행동의 차이.Go 1.14.7에서 Print 함수를 실행하고 Go1을 실행합니다.15시에 패닉이 떨어져요.
Go 1.15
$ go version
go version go1.15 linux/amd64
$ go run unexported.go
NumMethod=1
Method=0x48f340
panic: reflect: reflect.Value.Call using value obtained using unexported field
goroutine 1 [running]:
reflect.flag.mustBeExportedSlow(0x2b3)
/usr/local/go/src/reflect/value.go:237 +0x131
reflect.flag.mustBeExported(...)
/usr/local/go/src/reflect/value.go:228
reflect.Value.Call(0x4dd980, 0x5daf48, 0x2b3, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0)
/usr/local/go/src/reflect/value.go:335 +0x52
main.main()
/home/taka/tmp/unexported.go:22 +0x1ef
exit status 2
Go 1.14
$ go version
go version go1.14.7 linux/amd64
$ go run unexported.go
NumMethod=1
Method=0x488b20
Print!
수정 제출
이 근처에요?
감상
Go1.14까지 잘못된 행동이었으니 제대로 수정했죠.
그러나 사용자로서 패닉 여부를 어떻게 판별하는 것이 좋을까.모두 NumMethod()의 반환값이 같고 CanCall과 같은 검사 함수도 없습니다.
Reference
이 문제에 관하여(Go1.15에서 온 리플렉스 포장의 행위 차이에 대해), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/nokute/articles/62cb5482337940b14d1c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)