之前一直写Python, python本身是一门解释门语言, 所以我们会使用一些类似于golang中的反射方法, 我先拿python举个例子, 然后告诉你reflect到底是做什么的。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class ReflectMethodFactory(object):

    def __init__(self, action):
        self.action = action

    def most(self):
        print("max")

    def least(self):
        print("min")

    def random(self):
        print("random")

    def avg(self):
        print("avg")


def main():
    r = ReflectMethodFactory("most")
    getattr(r, r.action)()


if __name__ == "__main__":
    main()

上面这段代码, 首先根据构造方法传入对应的字符串, 然后进行解析出对应的方法, 然后调用, 在python中, getattr是动态类中的方法, 然后我在进行执行, 这是一个简单的例子, 那么实际使用中, 什么情况才会这么用呢? 其实它类似于工厂方法, 再看一个例子:

使用动态方法映射
class ReflectMethodFactory(object):

    def __init__(self, action):
        self.action = action
        self.reflect = {
            "get": self.get,
            "post": self.post
        }

    def get(self):
        print("get")

    def post(self):
        print("post")


def main():
    r = ReflectMethodFactory("get")
    r.reflect[r.action]()


if __name__ == "__main__":
    main()
未使用动态方法映射
class ReflectMethodFactory(object):

    def __init__(self, action):
        self.action = action

    def get(self):
        print("get")

    def post(self):
        print("post")


def main():
    r = ReflectMethodFactory("get")

    if r.action == "get":
        r.get()

    elif r.action == "post":
        r.post()
    
    # ..... else else

如果不实用动态映射的话, 来一个方法我就需要加一个if, 我事先定义好一组规则, 然后进行动态映射, 这样是不是方便了很多? 本身是弱类型语言所以可以这么搞, 但是golang中就不能这么搞, 所以才有了reflect

在看一个案例, 然后我们就将golang中使用

class ReflectMethodFactory(object):

    def __init__(self):
        self.a = 10
        self.b = 20


def main():
    r = ReflectMethodFactory()

    field = "a"

    print(r.__dict__[field])

结果是10, 动态映射类中的方法

golang
  • 动态映射方法
  • 动态映射结构体中的字段

需求如下: 根据传入的字符串进行动引用结构体中的字段。

type ReflectFactory struct {
	Name string
	Age int
}

func (s *ReflectFactory) A() {
	fmt.Println("A")
}

func (s *ReflectFactory) B() {
	fmt.Println("B")
}

func main() {
	r := ReflectFactory{Name:"Ellison"}

	field := "Name"

	res := reflect.ValueOf(&r).Elem().FieldByName(field).String()
	fmt.Println(res)
}

需求如下: 根据传入的字符串进行动引用结构体中的方法并执行。

type ReflectFactory struct {
	Name string
	Age int
}

func (s *ReflectFactory) A(action string) string {
	return action
}

func (s *ReflectFactory) B(action string) string {
	return action
}

func main() {
	r := ReflectFactory{Name:"Ellison"}
    
    // 方法名称
	field := "B"

	valueS := reflect.ValueOf(&r)
	method := valueS.MethodByName(field)

	params := []reflect.Value{
		reflect.ValueOf(field), // 方法参数
	}

	res := method.Call(params)[0].String() // 返回的是字符串

	fmt.Println(res)

}

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐