爱会让人有一种归属感,
像是回家的感觉,
极致的爱充满温柔 暴力
期待 掠夺,
完全的打开,
在只言片语中感受
对方的喜悦 不满,
然后不断建立新的内心建设
他经历过一段很长的恋爱,才发现,
在爱情里,
对不爱你的人付出太多,
对双方都是负担
调试是程序员的核心能力。在说到调试的时候,能体现出寻找问题往往比思考解决问题更重要(爱因斯坦说的)。
调试(debug)在工作的时候是经常发生的,我们需要通过调试寻找问题或者了解代码的工作内容。如果代码涉及到新的语言或者框架,调试也是学习语言和框架的一种不错的方式。
一般来说,分为2类调试方式:第一类是通过语言自带的打印工具,比如go里面的fmt.Prinitln方法等,这种方式比较基础;第二类是通过IDE调试,这种方式可以更好的控制代码的执行过程。
掌握更强大的调试技巧,会明显提高debug的效率。下面来说说goland里面那些好用的调试技巧。
先准备一段代码来进行调试
package main
import (
"fmt"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
)
const (
readTimeout = 5
writeTimeout = 10
idleTimeout = 120
)
func indexHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
returnStatus := http.StatusOK
w.WriteHeader(returnStatus)
message := fmt.Sprintf("Hello %s!", r.UserAgent())
w.Write([]byte(message))
}
func main() {
serverAddress := ":8080"
m := mux.NewRouter()
m.HandleFunc("/", indexHandler)
srv := &http.Server{
Addr: serverAddress,
ReadTimeout: readTimeout * time.Second,
WriteTimeout: writeTimeout * time.Second,
IdleTimeout: idleTimeout * time.Second,
Handler: m,
}
if err := srv.ListenAndServe(); err != nil {
panic(err)
}
}
第一步:进入调试状态
一般我们会以debug方式启动项目
第一个:快速计算表达式
可以选中一个语句或者一个表达式,然后按alt+f8,会弹出一个框,点击Evaluate,就可以查看表达式的值,你也可以在输入框修改表达式,再计算新的表达式。
另一种方式如下图
第二个:修改变量的值
注意:修改的变量的类型必须不是string类型的,可以修改int,float,bool等变量的值。
先在debug框里面选中变量,然后按f2,输入新的变量值
第三个:快速添加一个断点
添加一个断点一般有2类方式:第一类是在某一行代码左边左击;第二类是把光标放在一行的任何位置,然后按ctrl+f8。
debug我们一般是围绕着断点展开的,断点的类型常见的有:行断点(line breakpoint)和方法断点(method breakpoint)
行断点:方法/函数里面的某行的断点是行断点 方法断点:在方法的定义行上的断点
当我们的断点很多的时候,我们可以通过按ctrl+shift+f8,可以弹出一个管理断点的框。
如下
在这个页面,我们可以通过取消勾选某些断点来让某些断点取消。
勾选Suspend execution的意思是在断点的地方挂起程序,这是默认的行为,如果不勾选,程序不会在断点的地方挂起。
我们还可以给断点加上条件,只有满足条件的时候,断点才会挂起。在Condition下面的输入框输入条件。常见的用处比如for循环的我们想看某一次循环的情况,其他的时候跳过。
for i:=0;i<99;i++{
//do your own logic
}
Remove once hit:勾选这个可以让你的断点是临时的,当满足断点条件之后,就会自动取消这个断点
断点管理框里面还有一些其他功能,为了方便理解,我们可以使用面向对象的思想,对象是断点,使断点生效,失效,给断点加条件等都是断点的属性和行为
第四个:快速查看goroutine里面的调试信息
多协程的程序本身会增大程序的复杂度,也不容易调试。不过goland提供了查看某个协程信息的功能。
func main(){
num:=2
go func(name string){
makeRequest(name)
}
}
func makeRequest(name string){
// do something
fmt.Println(name)
}
在下图,左边下拉框选择对应的goroutine,就可以查看这个goroutine里面的调试信息。
第五个:让时光倒流,回到上一次
使用drop frame:frame是每次有函数调用的时候就会产生frame,当你在一个函数外边打了断点,然后在这个函数里面也打了断点,这时候手快,或者在进入这个函数之后,忘了函数外边断点的某个变量的值,想再次回到函数外边的这个断点,就可以点击 drop frame。
第六个:快速执行到光标处
使用快捷键ctrl+f9。f8类似于步兵作战(不能飞),f9类似近距离导弹(能让子弹飞一会),ctrl+f9类似于远程导弹作战(让子弹多飞一会)。
func main(){
// 比如你的断点在第3行,
// 如果你想看到第9行的情况,除了一直按f8,
// 可以把光标放在第9行,直接用ctrl+f9
a1:=1
a2:=2
sum:=a1+a2
sum+=sum+2
fmt.Println(sum)
}
第七个:快速修改断点位置
如果你不小心把断点的位置打错了,你可以先取消这个断点,再重新打断点,不过更快的方式是常按住鼠标左键,然后就可以拖动这个断点了。
