是否可以使用默认缩进级别来增强fmt.print? “概念证明” 注释

问题描述

我正在创建模块并使其相互链接。

测试行为时,我正在调用会调用其他程序包的程序包。

有没有一种简便的方法可以通过将来调用的缩进级别来修改fmt软件包的行为。 这样,父级可以在调用子级包之前设置缩进级别+1。

这样,当每个函数打印输出时,我可以轻松地在stdout中看到级联依赖关系:

inside main
calling package X
____entering package X
____calling package Y
________package Y hello world
____leaving package X
back in main.
exiting 

解决方法

fmt软件包不支持此功能。

但是,您可以借助runtime.Callers()访问通话深度,这意味着您甚至不必手动保持缩进“级别”。

“概念证明”

访问呼叫深度是这样的(对于0返回main(),对于从1调用的函数返回main()等):

func callDepth() int {
    pc := make([]uintptr,100)
    return runtime.Callers(6,pc)
}

并使用它,具有自动压痕打印功能:

var tabs = strings.Repeat("\t",100)

func Println(args ...interface{}) {
    fmt.Print(tabs[:callDepth()])
    fmt.Println(args...)

}

让我们看看它的作用:

func main() {
    Println("In main()")
    f1()
    Println("In main() again")
}

func f1() {
    Println("In f1()")
    f2()
    Println("In f1() again")
}

func f2() {
    Println("In f2()")
}

哪个输出(在Go Playground上尝试):

In main()
    In f1()
        In f2()
    In f1() again
In main() again

注释

我称上述解决方案为“概念验证”,因为它不是解决所有情况的解决方案。您必须决定在启动新的goroutine时要如何处理。当启动新的goroutine时,不会从main()中调用它们,因此传递给runtime.Callers()的跳过帧应少1(runtime.Callers(5,pc)而不是runtime.Callers(6,pc))。有关如何检测到此错误的信息,请参见Check if function is being called as goroutine or not

,

围绕想要运行的fmt函数编写一些包装,以便它们采用缩进级别的额外参数

package main

import "fmt"

// Println  replacement
func Println(level int,args ...interface{}) {
    for i := level; i > 0; i-- {
        fmt.Print("__")
    }
    fmt.Println(args...)
}

func main() {
    Println(0,"here")
    Println(1,"there")
    Println(2,"everywhere")
    Println(2,"Yes,everywhere")
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...