听说它可以让代码更优雅

news2024/9/9 5:35:22

一提到静态代码检查工具这个词应该比较好理解,所谓静态代码检查工具就是检查静态代码的工具,完美~

言归正传,相信很多程序员朋友都听说过静态代码检查工具这个概念,它可能是我们IDE里的某一个插件,可能是计算机中的一个程序,还可能是Git提交后的一个流程,如果是对代码要求比较高的个人或组织,静态代码检查工具则是一个绕不开的东西。

一个事物的出现必然是有所需求的,那么我们不妨先思考一下,为什么需要静态代码检查工具?

先抛开这个问题本身,我们从编译器的错误检查开始。

编译器:最严重代码的问题我替你规避

大家都知道我们写的代码是需要通过编译器编译成中间代码或可执行文件的,比如Java程序代码会由Java编译器编译成class文件,由JVM执行,Go代码会由Go编译器编译成二进制文件直接执行,中间都会有一个编译的过程,在编译原理中会有两个比较重要的流程——词法分析和语法分析。先说下词法分析和语法分析主要是用来做什么的:

词法分析是编译过程的第一步,其主要作用和特点如下:

  • 扫描源程序:词法分析器负责读入源程序的字符流,这是编译过程的输入。
  • 识别单词符号:根据源语言的词法规则,词法分析器将字符流分解并识别出各个单词符号。单词是源程序中的最小语义单位,如关键字、标识符、常数、运算符等。
  • 输出记号序列:词法分析器将识别出的单词符号转换成相应的记号(token)序列,作为语法分析的输入。每个记号通常包括一个词法单元名称(如关键字、标识符等)和一个可选的属性值(如标识符的名称、常数的值等)。
  • 过滤空白和注释:词法分析器还会跳过源程序中的空白字符(如空格、制表符等)和注释,这些对语法分析来说是无意义的。
  • 错误检测:词法分析器能够识别并报告词法错误,即非法的字符或单词符号,如非法字符、未识别的关键字等。

语法分析是在词法分析的基础上进行的,其主要作用和特点如下:

  • 分析语法结构:语法分析器根据语言的语法规则,对词法分析器输出的记号序列进行分析,以识别出各种语法单位,如表达式、语句、函数等。
  • 构建语法树:在语法分析过程中,通常会构建一棵语法树来表示源程序的语法结构。语法树的叶子节点通常对应于记号,而非叶子节点则对应于语法单位。
  • 错误检测和处理:语法分析器能够识别并报告语法错误,即不符合语法规则的记号序列。这些错误通常包括括号不匹配、缺少分号、语法单位使用不当等。
  • 为后续阶段做准备:语法分析的结果(如语法树)将作为后续阶段(如语义分析、代码生成等)的输入。通过语法分析,编译器能够确保源程序在语法上是正确的,从而可以进一步进行语义分析和代码生成等工作。

词法分析和语法分析是编译过程中不可或缺的两个阶段。词法分析负责将源程序的字符流转换成记号序列,而语法分析则根据语法规则对记号序列进行分析,以构建出源程序的语法结构。这两个阶段共同为后续的编译工作打下了坚实的基础,确保了编译过程的顺利进行。

现在我们知道了,词法分析和语法分析有一个共同的作用:错误监测

举个例子,我们使用Go中一个fmt包中不存在的函数:

package main

import "fmt"

func main() {
	fmt.Printlnx("Hello World")
}

执行后报错,原因很简单,因为函数的单词拼错了:

.\main.go:6:6: undefined: fmt.Printlnx

再有一个例子:

package main

import "fmt"

func main() {
	fmt.Println(str)
	str := "Hello World"
}

执行后同样报错,因为在程序中我们规定语法是先声明后使用,这段代码却是先使用后声明

.\main.go:6:14: undefined: str
.\main.go:7:2: str declared and not used

这两段代码其实主要是想阐述一件事:重大的程序问题编译器层面直接就不会编译通过。

静态代码检查工具:代码不优雅的地方我给你指出

那么有没有编译器发现不了的程序问题? 答案肯定是有的,举例子:

看这段代码:

package main

import "fmt"

func main() {
	str := "Hello World"
	fmt.Printf("%d \n",str)
}

一个很显然的问题,字符串应该使用%s进行转义,但该程序中使用的是表示整型变量的%d,但这个问题如果直接执行的话并不会报错,而是会打印出如下代码:

%!d(string=Hello World)

虽然我们写错了,但是Go程序还是会把我们想打印的数据打印出现并标记正确的类型,这个赞我点给Go的开发者!

还有这个:

package main

func hello() (string, error) {
	return "Hello", nil
}

func main() {
	hello()
}

从优雅的角度来讲,我们应该去认真处理每个函数中的错误返回值,但是以上示例中并没有处理,编译器也编译通过了,这样就导致程序中一旦真的返回了错误,那么排查问题可能就不太方便。

除了以上两个示例,Go程序中还要很多常见的编码问题需要注意,在大型项目中我们不可能逐行代码的去看,因此衍生出了静态代码检查工具这个东西。回答文章开头的问题,进行静态代码检查的原因主要有以下几点:

提高代码质量。 静态代码检查能够在不运行代码的情况下,通过自动化的方式分析代码,帮助开发者及时发现并修复潜在的缺陷以及不符合编码规范的问题。这有助于提升代码的整体质量,减少因代码问题导致的错误和故障。

降低维护成本。产品是资产,代码是负债,因为代码越多就一定程度上意味着维护成本越高。 高质量的代码意味着更低的维护成本。通过静态代码检查,开发者可以在早期发现并解决潜在问题,避免在后期测试和维护阶段投入更多的时间和资源。除此之外,还可以确保所有成员都遵循相同的编码规范,减少因风格不一致而导致的代码合并冲突。

Go语言如何进行静态代码检查

Go语言作为一门非常简单的编程语言,语法可以非常灵活,静态代码检查的方式也非常多,主要有以下几种方式:

使用内置的go vet工具go vet是Go语言内置的一个静态分析工具,它可以帮助开发者检查Go代码中的潜在问题,如未使用的变量、错误的使用标志位等。

使用golint工具golint是一个用于Go代码的Lint工具,它可以帮助开发者找出一些可疑的或者不规范的代码写法,如导出的函数没有注释、变量名不符合规范等,但本项目官方已经不再维护。

使用第三方静态分析工具:Go语言社区还提供了许多第三方静态分析工具,如staticcheckerrcheck等。这些工具通常具有更丰富的功能和更强大的检测能力,可以帮助开发者更全面地检查代码中的潜在问题。

集成到持续集成/持续部署(CI/CD)流程中:为了自动化地进行静态代码检查,开发者可以将静态分析工具集成到项目的CI/CD流程中。每次代码提交或合并时,都会自动运行静态检查工具,确保代码质量符合要求。

使用IDE插件:如GoLand、Visual Studio Code在的一些代码检查插件可以在编写代码的过程中实时提供静态检查反馈,帮助开发者及时发现并修复问题。

现在有哪些工具我们大概知道了,怎么用具体还是要试一试,比如刚刚的这段代码,我们使用go vet工具检查一下:

package main

import "fmt"

func main() {
	str := "Hello World"
	fmt.Printf("%d \n",str)
}

使用命令go vet main.go输出结果,可以看出它会把问题表达的很清楚:

.\main.go:7:2: fmt.Printf format %d has arg str of wrong type string

对于第二段代码,我们也可以有一个三方插件来进行代码检查,安装:go install github.com/kisielk/errcheck@latest

package main

func hello() (string, error) {
	return "Hello", nil
}

func main() {
	hello()
}

然后使用命令errcheck main.go,就会输出如下来告诉你哪行代码哪个方法没有处理错误返回值

main.go:8:7:    hello()
最好用的Go静态代码检查工具:golangci-lint

golangci-lint 可以说是一个大一统,它几乎把所有最有用的Go静态代码检查工具进行统一,并且还支持在CI/CD中使用。

官网:https://golangci-lint.run

Github:https://github.com/golangci/golangci-lint

我们可以使用命令golangci-lint help linters查看它都支持哪些静态检查工具(打印很多没截全):

可以看到有些是默认支持,有些是默认关闭支持的,我们不妨来试一下它和上面的两个工具有什么不同,我们将上面的两个代码示例合并到一起执行,运行命令golangci-lint run main.go

main.go:13:7: Error return value is not checked (errcheck)
        hello()
             ^
main.go:11:2: printf: fmt.Printf format %d has arg str of wrong type string (govet)
        fmt.Printf("%d \n",str)
        ^

可以看出这个工具打印的提升更加精准。后面如果想要继续深入可以阅读一下官方文档。

小总结

总的来说,静态代码检查工具是一个能够提升我们代码质量的工具,可以发现编译器发现不了的问题。这些工具的使用可以显著提高软件质量,所以大家赶快掌握起来,写出更优雅的代码!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

比 faster-whisper 至少快10倍的音视频转换文字

背景介绍 前两天我自己玩玩搞搞一个音频转文字服务,基于 faster-whisper,本想着这个已经是很快的了,没想到还有比它更快的,今天就来介绍使用一下。 FunClip,是阿里巴巴推出的一个智能视频剪辑工具,它结合…

计算机毕业设计选题推荐-某炼油厂盲板管理系统-Java/Python项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

[Bugku] web-CTF靶场详解!!!

平台为“山东安信安全技术有限公司”自研CTF/AWD一体化平台,部分赛题采用动态FLAG形式,避免直接抄袭答案。 平台有题库、赛事预告、工具库、Writeup库等模块。 ------------------------------- Simple_SSTI_1 启动环境: 页面提示传入参数f…

【Qt】QLCDNumberQProgressBarQCalendarWidget

目录 QLCDNumber 倒计时小程序 相关属性 QProgressBar 进度条小程序 相关设置 QLCDNumber QLCDNumber是Qt框架中用于显示数字或计数值的小部件。通常用于显示整数值,例如时钟、计时器、计数器等 常用属性 属性说明intValueQLCDNumber显示的初始值(int类型)va…

【全面介绍下Gitea,什么是Gitea?】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

这几个高级爬虫软件和插件真的强!

亮数据(Bright Data) 亮数据是一款强大的数据采集工具,以其全球代理IP网络和强大数据采集技术而闻名。它能够轻松采集各种网页数据,包括产品信息、价格、评论和社交媒体数据等。 网站:https://get.brightdata.com/we…

ubuntu安装并配置flameshot截图软件

参考:flameshot key-bindins 安装 sudo apt install flameshot自定义快捷键 Settings->Keyboard->View and Customize Shortcuts->Custom Shortcuts,输入该快捷键名称(自定义),然后输入command(…

RFID物流智能锁在物流锁控领域的意义与应用

在当今全球化和电子商务迅速发展的时代,物流行业作为经济的重要支撑,面临着日益增长的安全、效率和管理需求。物流锁控作为保障货物在运输过程中安全与完整的关键环节,传统的机械锁和简单电子锁已经难以满足现代物流复杂多变的业务场景。 一、…

前缀表达式(波兰式)和后缀表达式(逆波兰式)的计算方式

缀是指操作符。 1. 前缀表达式(波兰式) (1)不需用括号; (2)不用考虑运算符的优先级; (3)操作符置于操作数的前面。(如 3 2 ) 1.1 中…

3.5.3、查找和排序算法-插入类排序和选择类排序

术语说明 稳定:如果a原本在b前面,而ab,排序之后a仍然在b的前面; 不稳定:如果a原本在b的前面,而ab,排序之后a可能会出现在b的后面; 例如:数组{1,2,3,3,4,7,6}。如果排序后,两个3的位…

【嵌入式之RTOS】死锁问题详解

目录 一、什么是死锁 二、产生死锁的四个必要条件 三、避免死锁的方法 四、实际应用中的考虑 一、什么是死锁 死锁(Deadlock)是多任务或多线程环境中一个常见的问题,尤其是在实时操作系统(RTOS)中,如果…

kvm虚拟化平台部署

kvm虚拟化平台部署 kvm概念简介 kvm自linux2.6版本以后就整合到内核中,因此可以看做是一个原生架构. kvm虚拟化架构 硬件底层提供物理层面的硬件支持 linux(host),就相当于这个架构中的宿主机,上面运行了多个虚拟机。…

替换后端国外身份目录服务,宁盾身份域管接管FileNet助力国产化升级

IBM FileNet 是一款优秀的企业内容管理解决方案,为客户提供了领先的文档管理和流程管理集成环境,被大量企业所采用。FileNet 需要使用企业级的目录服务器(LDAP)作为其用户管理系统,满足其认证和授权的需求。对于 LDAP …

最高200万!苏州成都杭州的这些AI政策补贴,你拿到了吗?

随着全球人工智能技术的迅猛发展,地方政府纷纷出台相关政策以抢占未来科技的制高点。苏州 成都 杭州这三个城市更是推出了一系列AI政策补贴,旨在通过多方面支持,推动本地AI产业的发展。本文将带你了解目前不完全统计到的苏州 成都 杭州三地AI…

【Vulnhub系列】Vulnhub_pipe 靶场渗透(原创)

【Vulnhub系列靶场】Vulnhub-pipe 靶场渗透 原文转载已经过授权 原文链接:Lusen的小窝 - 学无止尽,不进则退 (lusensec.github.io) 一、环境配置 1、解决IP扫描不到问题 2、打开虚拟机,并修改网络连接模式为【NAT】即可 二、信息收集 1…

Python实战——轻松实现动态网页爬虫(附详细源码)

大家好&#xff0c;我是东眠的鱼&#xff0c;专注原创&#xff0c;致力于用浅显易懂的语言分享爬虫、数据分析及可视化等干货&#xff0c;希望人人都能学到新知识。<文末附带精品籽料哦&#xff0c;也可以和博主一起学Python呀&#xff01;> 项目背景 有同学自学爬虫时…

前端vue3 巧妙的checkbox 选中框样式

我们 做前端页面交互效果的时候 我们会使用到 checkbox 复选框 做一些交互的效果 我是用的是 nut-ui 组件库中的 checkbox 组件 类似于这样的选中效果 假如 二选一的那种 可以 这样写 交互好看 而不是单纯的 checkbox 框 这里我就不使用 gif 图片了 大家应该都可以看懂的 …

A股继续震荡下行,成交量继续一蹶不振。

A股继续震荡下行&#xff0c;成交量继续一蹶不振。今天的A股&#xff0c;让人揪心不已&#xff0c;你们知道是为什么吗&#xff1f;盘面上出现1个重要信号&#xff0c;一起来看看&#xff1a; 1、今天两市低开低走&#xff0c;向下回补了2867点的缺口&#xff0c;让人揪心不已。…

计算机毕业设计选题推荐-基于司机信用评价的货运管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

CUDA_Occupancy_Calculator计算公式

CUDA_Occupancy_Calculator计算公式