-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
reflect: no way to tell whether a method is value method or not #20995
Comments
type Foo struct{}
func (f Foo) Check() {}
func main() {
var foo *Foo
foo.Check()
} This panics:
Thus, I would expect reflect to also panic. |
@dsnet I know it will panic but what I want to do is get the original receiver type of the method to determine whether to invoke Call. |
Here's an example of how to check for the type Foo struct{}
func (f Foo) Check() {}
func main() {
var foo *Foo
v := reflect.ValueOf(foo)
method, _ := v.Type().Elem().MethodByName("Check")
fmt.Println(method.Type)
} If you try to do the same on Bar, it will not find the |
I'm going to mark this as resolved. The API in reflect allows you to do what you're asking for. It's not the nicest, but the reflect API is already pretty bloated that I don't think we would add new API surface just for this use-case. |
@dsnet
Your approach does not help in above situation, MethodByName will not return nil for fieldType or fieldType.Elem(). I can workaround this by wrap method calling in defer/recover and check panic message against "value method ... called using nil ... pointer", but it's obviously too hacky. |
You can replace: methodIsValueMethod := false // TODO how?
if fieldType.Kind() == reflect.Ptr && field.IsNil() && methodIsValueMethod {
continue
} with: if fieldType.Kind() == reflect.Ptr && field.IsNil() {
// Method defined on a value receiver.
if _, ok := fieldType.Elem().MethodByName("Check"); ok {
continue // Ignore since value can't be retrieved from nil pointer
}
} |
@dsnet got it. tricky but works. |
welcome to reflect ;) |
What version of Go are you using (
go version
)?go version devel +75f1de8329 Wed Jul 12 23:39:39 2017 +0000 linux/amd64
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/reus/go"
GORACE=""
GOROOT="/home/reus/gotip"
GOTOOLDIR="/home/reus/gotip/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build623176799=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
What did you do?
What did you expect to see?
a proper way to skip Call to avoid panic
What did you see instead?
panic randomly
The text was updated successfully, but these errors were encountered: