首页 > 编程语言 >学习go语言编程之工程管理

学习go语言编程之工程管理

时间:2023-08-15 21:56:00浏览次数:35  
标签:语言 工程 代码 编程 单元测试 Go go 目录

Go命令行工具

安装了Go语言的安装包后,就直接自带Go命令行工具。

# 查看当前安装的Golang版本
go version

# 查看go命令行工具的帮助信息
go help

Go命令行工具可以完成如下工作:

  • 代码格式化
  • 代码质量分析和修复
  • 单元测试与性能测试
  • 工程构建
  • 代码文档的提取和展示
  • 依赖包管理
  • 执行其他的包含指令

代码风格

代码风格,是一个与人相关、与机器无关的问题。
代码风格的好坏,不影响编译器的工作,但是影响团队协同,影响代码的复用、演进以及缺陷修复。

强制性编码规范

命名

命名规则涉及变量常量全局函数结构接口方法等的命名。
Go语言从语法层面进行了以下限定:任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。
软件开发行业最流行的两种命名法分别为驼峰命名法和下划线法,Go语言明确宣告了拥护驼峰命名法而排斥下划线法。

排列

Go语言甚至对代码的排列方式也进行了语法级别的检查,约定了代码块中花括号的明确摆放位置。

非强制性编码风格建议

使用go fmt命令可以对代码进行格式化,例如:

# 格式化单个Golang源文件
go fmt hello.go

更详尽的用法可以查看:go help fmt

当然,这个工具并非只能一次格式化一个文件,比如不带任何参数直接运行go fmt的话,可以直接格式化当前目录下的所有*.go文件,或者也可以指定一个GOPATH中可以找到的包名。

远程import支持

Go语言不仅允许我们导入本地包,还支持在语言级别调用远程的包。
假如,有一个用于计算CRC32的包托管于Github,那么可以这样写:

package main 
import ( 
    "fmt" 
    "github.com/myteam/exp/crc32" 
)

在执行go build或者go install之前,只需要加这么一句:go get github.com/myteam/exp/crc32
当执行完go get之后,会在src目录中看到github.com目录,其中包含myteam/exp/crc32目录。在crc32中,就是该包的所有源代码。
也就是说,go工具会自动获取位于远程的包源码,在随后的编译中,也会在pkg目录中生成对应的.a文件。

工程组织

GOPATH

Go命令行工具大部分功能其实不再针对当前目录,而是针对包名,于是如何才能定位到对应的源代码就落到了GOPATH环境变量身上。
假设现在本地硬盘上有3个Go代码工程,分别为~/work/go-proj1~/work2/goproj2~/work3/go-proj3,那么GOPATH可以设置为如下内容:

export GOPATH=~/work/go-proj1:~/work2/goproj2:~/work3/go-proj3

经过这样的设置后,就可以在任意位置对以上的3个工程进行构建。

目录结构

一个完整的Go项目工程结构通常如下:

<calcproj>
  - README
  - LICENSE
  - bin
    - calc
  - pkg
    - <linux_amd64>
      - simplemath.a
  - src
    - calc
      - calc.go
    - simplemath
      - add.go
      - add_test.go
      - sqrt.go
      - sqrt_test.go

Go语言工程不需要任何工程文件,一个比较完整的工程会在根目录处放置这样几个文本文件。

  • README:简单介绍本项目目标和关键的注意事项,通常第一次使用时应该先阅读本文档。
  • LICENSE:本工程采用的分发协议,所有开源项目通常都有这个文件。

一个标准的Go语言工程包含以下几个目录:srcpkgbin
src用于包含所有的源代码,这是Go命令行工具的一个强制的规则,而pkgbin则无需手动创建,如果必要Go命令行工具在构建过程中会自动创建它们。
构建过程中Go命令行工具对包结构的理解完全依赖于src下面的目录结构。

文档管理

所谓的文档,更多的是指代码中的注释、函数、接口的输入、输出、功能和参数说明,这些对于后续的维护和复用有着至关重要的作用。
Go语言让开发者完全甩掉注释语法的包袱,专注于内容。

// Copyright 2011 The Go Authors. All rights reserved. 
// Use of this source code is governed by a BSD-style 
// license that can be found in the LICENSE file.

/* 
Package foo implements a set of simple mathematical functions. These comments are for 
demonstration purpose only. Nothing more. 
If you have any questions, please don’t hesitate to add yourself to 
[email protected]. 
You can also visit golang.org for full Go documentation. 
*/
package foo

import "fmt"

// Foo compares the two input values and returns the larger 
// value. If the two values are equal, returns 0. 
func Foo(a, b int) (ret int, err error) { 
    if a > b { 
        return a, nil
    } else { 
        return b, nil
    } 
    return 0, nil
}

// BUG(jack): #1: I'm sorry but this code has an issue to be solved. 
// BUG(tom): #2: An issue assigned to another person.

如上代码文档示例中,添加了4条注释:版权说明注释、包说明注释、函数说明注释和最后添加的遗留问题说明。

关于注释的编写,要遵守如下的基本规则:

  • 注释需要紧贴在对应的包声明和函数之前,不能有空行。
  • 注释如果要新起一个段落,应该用一个空白注释行隔开,因为直接换行书写会被认为是正常的段内折行。
  • 开发者可以直接在代码内用// BUG(author): 的方式记录该代码片段中的遗留问题,这些遗留问题也会被抽取到文档中。

工程构建

使用go build命令来执行构建,它会在你运行该命令的目录中生成工程的目标二进制文件,而不产生其他结果。
如果项目工程路径已经被加入到了全局变量GOPATH中,可以在任意位置执行go build命令,而不必关心是否能找到源代码。
注意: 在构建可执行程序工程时,会在当前所在的目录中生成可执行程序,所以通常选择在项目目录下的bin目录中执行构建。

构建示例如下:

# calc是项目src目录下的包名
go build calc

单元测试

Golang本身提供了一套轻量级的测试框架,符合规则的测试代码会在运行测试时被自动识别并执行。
单元测试源文件的命名规则如下:在需要测试的包下面创建以“_test”结尾的go文件,形如[^.]*_test.go

Golang的单元测试函数分为两类:功能测试函数和性能测试函数,分别为以TestBenchmark为函数名前缀并以*testing.T*testing.B为单一参数的函数。
示例如下:

// 功能测试函数以Test为函数名前缀
func TestAdd1(t *testing.T) 
// 性能测试函数以Benchmark为函数名前缀
func BenchmarkAdd1(t *testing.B)

测试工具会根据函数中的实际执行动作得到不同的测试结果:功能测试函数会根据测试代码执行过程中是否发生错误来返回不同的结果,而性能测试函数仅仅打印整个测试过程的花费时间。

功能单元测试

功能单元测试示例代码:

func TestAdd(t *testing.T) {
	r := Add(1, 2)
	if r != 3 {
		t.Errorf("Add(1,2) failed. Got %d, expected 3.", r)
	}
}

执行功能单元测试非常简单,直接执行go test命令即可。

# 执行当前所在包的所有单元测试
go test

当然,也可以在IDE中对单个方法执行单元测试。

性能单元测试

性能单元测试示例代码:

func BenchmarkAdd(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Add(1, 2)
	}
}

性能测试与功能测试代码相比,最大的区别在于代码里的这个for循环,写这个for循环的原因是为了能够让测试运行足够长的时间便于进行平均运行时间的计算。

如果测试代码中一些准备工作的时间太长,也可以这样处理以明确排除这些准备工作所花费时间对于性能测试的时间影响:

func BenchmarkAdd(b *testing.B) {
    b.StopTimer()   // 暂停计时器
    DoPreparation() // 一个耗时较长的准备工作,比如读文件
    b.StartTimer()  // 开启计时器,之前的准备时间未计入总花费时间内

	for i := 0; i < b.N; i++ {
		Add(1, 2)
	}
}

标签:语言,工程,代码,编程,单元测试,Go,go,目录
From: https://www.cnblogs.com/nuccch/p/17632558.html

相关文章

  • 学习go语言编程之安全编程
    数据加密对称加密采用单密钥的加密算法,称为对称加密。常见的单密钥加密算法有DES、AES、RC4等。在对称加密中,私钥不能暴露,否则在算法公开的情况下,数据等同于明文。非对称加密采用双密钥的加密算法,称为非对称加密。在该系统中,私钥和公钥都可以被用作加密或者解密,但是用私钥......
  • 学习go语言编程之标准库
    标准库包分类Golang标准库可以大致按其中库的功能进行以下分类:分类对应包描述输入输出bufio,fmt,io,log,flag这个分类包括二进制以及文本格式在屏幕、键盘、文件以及其他设备上的输入输出等,比如二进制文件的读写。文本处理encoding,bytes,strings,strconv,text,mime,unico......
  • C语言数据的存储
    目录类型的基本归类整形在内存中的存储原码、反码、补码大小端介绍练习浮点型在内存中的存储浮点数存储的例子浮点数存储规则类型的基本归类整形家族:charunsignedcharsignedcharshortunsignedshort[int]signedshort[int]intunsignedint......
  • 使用 SpringData 操作 Mongodb
    本篇博客主要介绍SpringBoot如何通过SpringData操作Mongodb。在上篇博客部署的mongodb为了方便,在admin库中创建了一个root角色的账号,使用这个账号具有最高权限,可以访问和操作任何库。在实际项目中强烈建议为每个mongodb数据库创建一个低权限角色的用户,比如具有readw......
  • 14 观察者模式 -- go语言设计模式
    观察者模式也叫做发布-订阅模式。观察者通过通知器(发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者只从通知器得到它订阅的通知。观察者模式的实现代码packagemainimport"fmt"//---------抽象层--------//抽象的观察者typeListenerinterface{ OnTe......
  • R语言实现MCMC中的Metropolis–Hastings算法与吉布斯采样|附代码数据
    原文链接:http://tecdat.cn/?p=3772原文出处:拓端数据部落公众号 最近我们被客户要求撰写关于MCMC的研究报告,包括一些图形和统计输出。创建测试数据第一步,我们创建一些测试数据,用来拟合我们的模型。我们假设预测变量和因变量之间存在线性关系,所以我们用线性模型并添加一些噪音......
  • R语言进行支持向量机回归SVR和网格搜索超参数优化|附代码数据
    全文链接:http://tecdat.cn/?p=23305最近我们被客户要求撰写关于支持向量机回归的研究报告,包括一些图形和统计输出。在这篇文章中,我将展示如何使用R语言来进行支持向量回归SVR我们将首先做一个简单的线性回归,然后转向支持向量回归,这样你就可以看到两者在相同数据下的表现。一个......
  • R语言VAR模型的不同类型的脉冲响应分析|附代码数据
    原文链接:http://tecdat.cn/?p=9384原文出处:拓端数据部落公众号 最近我们被客户要求撰写关于VAR模型的研究报告,包括一些图形和统计输出。目录模型与数据估算值预测误差脉冲响应识别问题正交脉冲响应结构脉冲反应广义脉冲响应参考文献脉冲响应分析是采用向量自回归模......
  • JavaScript基础:学习JavaScript语言的基本语法和常用操作,了解网页交互的基本原理
    JavaScript是一种广泛应用于网页开发中的脚本语言,它可以与HTML和CSS一起使用,实现网页交互及动态效果。以下是JavaScript的基本语法和常用操作:变量声明:使用var、let或const关键字声明变量。varname="John";letage=25;constPI=3.14;数据类型:包括字符串、数字、布......
  • C语言中数组的基础知识
    数组是一种集合数据类型,它由多个元素组成,每个元素都有相同的数据类型,占有相同大小的存储单元,且在内存中连续存放。每个数组有一个名字,数组中的每个元素有一个序号(称为下标),表示元素在数组中的位置,数组的维数和大小在定义数组时确定,程序运行时不能改变。一维数组的定义形式为:类型说......