go 的 reflect 能按代码顺序获取 Method 吗?

如下,我希望能按方法在代码中的位置顺序获取方法,但go的反射似乎都会按照名称排序返回,我的需求有实现的方案吗?

1. 运行环境

go version go 1.16+

2. 问题描述?

代码:

type MyService struct{}

func (s *MyService) F1() {}
func (s *MyService) F3() {}
func (s *MyService) F5() {}
func (s *MyService) F2() {}
func (s *MyService) F4() {}
func (s *MyService) F6() {}

func TestReflect(t *testing.T) {
    s := &MyService{}
    rt := reflect.TypeOf(s)
    for i := 0; i < rt.NumMethod(); i++ {
        fmt.Println(rt.Method(i).Name)
    }
}

3. 您期望得到的结果?

=== RUN   TestReflect
F1
F3
F5
F2
F4
F6
--- PASS: TestReflect (0.00s)

4. 您实际得到的结果?

=== RUN   TestReflect
F1
F2
F3
F4
F5
F6
--- PASS: TestReflect (0.00s)
世界最好语言的追随者
最佳答案
package main

import (
    "fmt"
    "reflect"
    "runtime"
    "sort"
)

type MyService struct{}

func (s *MyService) F1() {}
func (s *MyService) F3() {}
func (s *MyService) F5() {}
func (s *MyService) F2() {}
func (s *MyService) F4() {}
func (s *MyService) F6() {}

func main() {
    s := &MyService{}
    rt := reflect.TypeOf(s)

    // 创建一个 map 用于存储行号和方法名
    methods := make(map[int]string)

    // 遍历方法名称和所在行号
    for i := 0; i < rt.NumMethod(); i++ {
        method := rt.Method(i)
        methodName := method.Name
        fn := runtime.FuncForPC(method.Func.Pointer())
        if fn != nil {
            _, line := fn.FileLine(0)
            methods[line] = methodName
        } else {
            fmt.Printf("Unable to get function information for method: %s\n", methodName)
        }
    }

    // 获取方法名称的切片
    var lines []int
    for line := range methods {
        lines = append(lines, line)
    }

    // 对行号进行排序
    sort.Ints(lines)

    // 按照升序输出
    for _, line := range lines {
        fmt.Printf("Line: %d, Method: %s\n", line, methods[line])
    }
}

输出:

Line: 12, Method: F1
Line: 13, Method: F3
Line: 14, Method: F5
Line: 15, Method: F2
Line: 16, Method: F4
Line: 17, Method: F6
2个月前 评论
renxiaotu (楼主) 2个月前
讨论数量: 2
package main

import (
    "fmt"
    "reflect"
    "runtime"
    "sort"
)

type MyService struct{}

func (s *MyService) F1() {}
func (s *MyService) F3() {}
func (s *MyService) F5() {}
func (s *MyService) F2() {}
func (s *MyService) F4() {}
func (s *MyService) F6() {}

func main() {
    s := &MyService{}
    rt := reflect.TypeOf(s)

    // 创建一个 map 用于存储行号和方法名
    methods := make(map[int]string)

    // 遍历方法名称和所在行号
    for i := 0; i < rt.NumMethod(); i++ {
        method := rt.Method(i)
        methodName := method.Name
        fn := runtime.FuncForPC(method.Func.Pointer())
        if fn != nil {
            _, line := fn.FileLine(0)
            methods[line] = methodName
        } else {
            fmt.Printf("Unable to get function information for method: %s\n", methodName)
        }
    }

    // 获取方法名称的切片
    var lines []int
    for line := range methods {
        lines = append(lines, line)
    }

    // 对行号进行排序
    sort.Ints(lines)

    // 按照升序输出
    for _, line := range lines {
        fmt.Printf("Line: %d, Method: %s\n", line, methods[line])
    }
}

输出:

Line: 12, Method: F1
Line: 13, Method: F3
Line: 14, Method: F5
Line: 15, Method: F2
Line: 16, Method: F4
Line: 17, Method: F6
2个月前 评论
renxiaotu (楼主) 2个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!