如何检查一个对象是否具有特定的方法?

huangapple go评论87阅读模式
英文:

How to check if an object has a particular method?

问题

在Go语言中,你如何检查一个对象是否响应某个方法?

例如,在Objective-C中可以通过以下方式实现:

if ([obj respondsToSelector:@selector(methodName:)]) { // 如果方法存在
  [obj methodName:42]; // 调用该方法
}

在Go语言中,可以使用反射(reflection)来实现类似的功能。你可以使用reflect包中的Value类型的MethodByName方法来检查对象是否具有指定名称的方法,并通过Call方法来调用该方法。下面是一个示例代码:

import "reflect"

func main() {
    obj := SomeObject{} // 假设有一个名为SomeObject的对象

    methodName := "MethodName" // 要检查的方法名称

    method := reflect.ValueOf(obj).MethodByName(methodName)
    if method.IsValid() { // 如果方法存在
        args := []reflect.Value{reflect.ValueOf(42)} // 方法的参数
        method.Call(args) // 调用方法
    }
}

type SomeObject struct {
    // SomeObject的定义
}

func (o SomeObject) MethodName(arg int) {
    // 方法的实现
}

请注意,上述示例中的SomeObject是一个自定义类型,你需要根据实际情况替换为你自己的类型。

英文:

In Go, how do you check if an object responds to a method?

For example, in Objective-C this can be achieved by doing:

if ([obj respondsToSelector:@selector(methodName:)]) { // if method exists
  [obj methodName:42]; // call the method
}

答案1

得分: 42

一个简单的选项是声明一个只包含你想要检查的方法的接口,然后对你的类型进行类型断言,例如:

i, ok := myInstance.(InterfaceImplementingThatOneMethodIcareAbout)
// 内联接口声明示例
i, ok = myInstance.(interface{F()})

如果你计划对你的类型进行一些复杂的操作,你可能需要使用reflect包;http://golang.org/pkg/reflect

st := reflect.TypeOf(myInstance)
m, ok := st.MethodByName("F")
if !ok {
    // 方法不存在
} else {
    // 做一些像调用m.F这样的操作
}
英文:

A simple option is to declare an interface with just the method you want to check for and then do a type assert against your type like;

 i, ok := myInstance.(InterfaceImplementingThatOneMethodIcareAbout)
 // inline iface declaration example
 i, ok = myInstance.(interface{F()})

You likely want to use the reflect package if you plan to do anything too crazy with your type; http://golang.org/pkg/reflect

st := reflect.TypeOf(myInstance)
m, ok := st.MethodByName("F")
if !ok {
    // method doesn't exist
} else {
    // do something like invoke m.F
}   

答案2

得分: 24

如果 obj 是 interface{} 类型,你可以使用 Go 类型断言:

if correctobj, ok := obj.(interface{methodName()}); ok { 
  correctobj.methodName() 
} 
英文:

If obj is an interface{} you can use Go type assertions:

if correctobj, ok := obj.(interface{methodName()}); ok { 
  correctobj.methodName() 
} 

答案3

得分: 0

只需在接口大括号 {write_function_declaration_here} 内部添加以下内容,即可完成 @evanmcdonnal 的解决方案:

if correctobj, ok := obj.(interface{methodName(func_arguments_here)(return_elements_here)}); ok { 
    x,... := correctobj.methodName() 
}

即:

package main

import "fmt"

type test struct {
    fname string
}

func (t *test) setName(name string) bool {
    t.fname = name
    return true
}

func run(arg interface{}) {
    if obj, ok := arg.(interface{ setName(string) bool }); ok {
        res := obj.setName("Shikhar")
        fmt.Println(res)
        fmt.Println(obj)
    }
}

func main() {
    x := &test{
        fname: "Sticker",
    }
    fmt.Println(x)
    run(x)
}
英文:

Just in addition to @evanmcdonnal's solution inside the interface braces {write_function_declaration_here}, you will write the function declaration

if correctobj, ok := obj.(interface{methodName(func_arguments_here)(return_elements_here)}); ok { 
 x,... := correctobj.methodName() 
} 

i.e.

package main

import "fmt"

type test struct {
	fname string
}

func (t *test) setName(name string) bool {
	t.fname = name
	return true
}

func run(arg interface{}) {
	if obj, ok := arg.(interface{ setName(string) bool });
		ok {
		res := obj.setName("Shikhar")
		fmt.Println(res)
		fmt.Println(obj)
	}
}

func main() {
	x := &test{
		fname: "Sticker",
	}
	fmt.Println(x)
	run(x)

}

huangapple
  • 本文由 发表于 2015年4月17日 03:48:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/29684609.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定