趁着近期要换工作的空闲时间,看了一下Go语言,与C++相比,Go语言的确在不少地方轻便了不少,例如:增加了内置的字符串类型、多个返回值、支持协程、简单的构建方法等等。使得在生产效率方面有了不少的提高。今天这里对Go语言的构建方法做个简单的总结。

在C/C++的工程中,极少使用单个命令来编译代码,一般是通过一些工具来进行自动化的编译,刚开始的时候手动写makefile,再后来是繁复的Autotools,之后又出现了CMake,按照时间的推移,所需我们做的工作越来越少,例如在Autotools我们大致需要如下工作:

  1. autoscan扫描工作目录,之后手动修改生成的configure.ac。
  2. 使用aclocal命令,通过configure.ac来生成aclocal.m4。
  3. 使用autoconf命令生成configure脚本。
  4. 使用autoheader命令生成config.h.in。
  5. 手动创建Makefile.am文件,按照工程需要配置后再使用automake命令来生成Makefile.in文件。
  6. 再执行configure脚本,最后生成Makefile。

完成上述步骤后,才可以make,make install 来完成工程的编译的安装。而之后的CMake则简便不少,只需要配置几个CMakeList.txt,之后执行CMake命令,即可生成编译和安装所需的Makefile文件。

虽然随着技术的发展,C/C++会有更好的构建方法出现。但目前看来,是摆脱不了Makefile的,而在Go1发布时,舍弃了Makefile,直接引入了更为方便的方法:**Go命令行工具**。

Go命令行工具直接舍弃的工程文件的概念,只通过目录结构和包的名字来推倒工程结构和构建顺序,下面我们使用一个简单的例子(取自《Go语言编程》)来说明下Go中的基本工程管理方法。

这个例子是一个基于命令行的计算器。基本用法如下所示:

$calc help
USAGE: calc command [argument] ... The Command are:
sqrt Square root of a non-negative value
add Addation of two values $ calc sqrt #对4进行开方 $ calc add

根据需求,我们可以把工程分为两个部分,主程序和算法库,这样,当我们算法进行更新的时候,只修改实现就可以了,而不用修改对外的接口,这样就可以达到低耦合。工程目录如下所示:

calculator
|----src
  |----calc
    |----calc.go
  |----simplemath
    |----add.go
    |----add_test.go
    |----sqrt.go
    |----sqrt_test.go
|----bin
|----pkg

在上面,斜体表示目录,正常文章表示文件,**xx_test.go表示是对xx.go的单元测试文件**,这是Go工程的命名规则。同时,工程下的目录src表示是源码目录,bin表示安装后的可执行程序目录,pkg表示包目录,这也是Go工程的命名规则。下面就是这个工程的代码了。
calc.go

// calc.go
package main

import (
    "fmt"
    "os"
    "simplemath"
    "strconv"
)

var Usage = func() {
    fmt.Println("USAGE: calc command [arguments]...")
    fmt.Println("\nThe commands are: \n\tAddition of two values.\n\tsqrt\tSquare root of a non-negative value")
}

func main() {
    args := os.Args
    if args == nil || len(args) < 2 {
        Usage()
        return
    }

    switch args[0] {
    case "add":
        if len(args) != 3 {
            fmt.Println("USAGE:calc add <integer1> <integer2>")
            return
        }
        v1, err1 := strconv.Atoi(args[1])
        v2, err2 := strconv.Atoi(args[2])
        if err1 != nil || err2 != nil {
            fmt.Println("USAGE:calc add <integer1> <integer2>")
            return
        }
        ret := simplemath.Add(v1, v2)
        fmt.Println("Result: ", ret)
    case "sqrt":
        if len(args) != 2 {
            fmt.Println("USAGE: calc sqrt <integer>")
            return
        }
        v, err := strconv.Atoi(args[1])
        if err != nil {
            fmt.Println("USAGE: calc sqrt <integer>")
            return
        }
        ret := simplemath.Sqrt(v)
        fmt.Println("Result: ", ret)
    default:
        Usage()
    }
}

add.go

 // add.go
package simplemath func Add(a int, b int) int {
return a + b
}

add_test.go

 // add_test.go
package simplemath import "testing" func TestAdd1(t *testing.T) {
r := Add(1, 2)
if r != 3 {
t.Errorf("Add(1, 2) failed, Got %d, expected 3", r)
}
}

sqrt.go

 // sqrt.go
package simplemath import "math" func Sqrt(i int) int {
v := math.Sqrt(float64(i))
return int(v)
}

由于篇幅问题,sqrt的单元测试代码在此省略。

完成代码后,就要进行编译了。首先需要设置环境变量**GOPATH**的值,将**calcuator的目录赋给GOPATH**,保存后重新载入即可。假设calcuator的目录是"~/gobuild",那么在linux下可以执行以下命令:

export GOPATH=~/gobuild/calcuator
source ~/.bashrc

设置完环境变量后,就可以开始构建工程了,进入calcuator的目录,执行命令:

cd bin
go build calc

之后就可以在目录下发现名字为calc的可执行程序。按照先前的功能进行试验,即可以看到对应的执行结果。

以上就是Go进行构建的过程,按照Go的要求组织好目录后,真正进行构建的就只是**go build calc**这条命令。可以说是非常简单快捷。而同样,进行单元测试,在bin目录下执行命令:
go test simplemath即可。

以上就是Go进行构建的一个简单总结。由于是刚开始接触Go语言,如果有错误的地方,请指正。谢谢
xiaoniu
[2/30]

参考资料:

Go语言编程

Go语言的构建方法总结的更多相关文章

  1. Go 语言中的方法,接口和嵌入类型

    https://studygolang.com/articles/1113 概述 在 Go 语言中,如果一个结构体和一个嵌入字段同时实现了相同的接口会发生什么呢?我们猜一下,可能有两个问题: 编译器会 ...

  2. Atitti 知识图谱构建方法attilax 总结

    Atitti 知识图谱构建方法attilax 总结   1.1. 知识图谱schema构建(体系化)1 1.2. 纵向垂直拓展(向上抽象,向下属性拓展)2 1.3. 横向拓展2 1.4. 网拓展2 1 ...

  3. [转贴]从零开始学C++之异常(一):C语言错误处理方法、C++异常处理方法(throw, try, catch)简介

    一.C语言错误处理方法 1.返回值(if … else语句判断错误) 2.errno(linux 系统调用) 3.goto语句(函数内局部跳转) 4.setjmp.longjmp(Do not use ...

  4. Oracle存储过程中不支持DML语言的解决方法(针对遇见的DROP关键字)

    ---存储过程中的原语句: ---删除表 DROP TABLE A_NEWTDDATA; --报错 经查询:存储过程不支持DML语言: 解决方法: execute immediate 'DROP TA ...

  5. 航道水下地形DEM构建方法比较

    论文<航道水下数字高程模型的构建方法> 对航道水下地形建立DEM,技术路线:先构建TIN,手动去除多余三角边,再利用CAD ObjectARX二次开发接口中提供的几种内插方法生成grid ...

  6. 从零开始学C++之异常(一):C语言错误处理方法、C++异常处理方法(throw, try, catch)简介

    一.C语言错误处理方法 1.返回值(if … else语句判断错误) 2.errno(linux 系统调用) 3.goto语句(函数内局部跳转) 4.setjmp.longjmp(Do not use ...

  7. Java学习之类的构建方法(函数)

    在学习类的部分时,建立一个对象是这样建立的:(假设Person是类)Person  p = new  Person():我一直很费解为何new后面是一个函数形式, 今天学完构建方法后,才恍然大悟,豁然 ...

  8. C语言错误处理方法、C++异常处理方法(throw, try, catch)简介

    一.C语言错误处理方法 1.返回值(if … else语句判断错误) 2.errno(linux 系统调用) 3.goto语句(函数内局部跳转) 4.setjmp.longjmp(Do not use ...

  9. Xamarin XAML语言教程构建ControlTemplate控件模板 (四)

    Xamarin XAML语言教程构建ControlTemplate控件模板 (四) 2.在页面级别中构建控件模板 如果开发者要在页面级别中构建控件模板,首先必须将ResourceDictionary添 ...

随机推荐

  1. activity theme parent 属性浅析

    在AndroidManifest.xml文件中,可以对每一个Activity设置android:themetheme的设置 可以设置为系统自带的格式,也可以自定义格式. A: 系统自带格式 1.and ...

  2. yii 笔记

    Yii1.1: $_GET 可以表示为 Yii::app()->request->getQuery() $_POST 可以表示为 Yii::app()->request->po ...

  3. lesson7:java线程池

    在jdk1.5的版本中,java提供了语言级别的线程池,对于需要使用线程池的业务系统和中间件框架等提供了方便的选择.我认为线程池主要有两个方面的作用:第一就是防止因为外部条件的变化,造成线程数的瞬间飙 ...

  4. Linux输出重定向

  5. [转]getResource()和getResourceAsStream以及路径问题

    原文链接:http://blog.sina.com.cn/s/blog_4b5bc0110100g22w.html 用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉 ...

  6. 使用Mina框架开发 QQ Android 客户端

    Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步AP ...

  7. 【iOS开发之OC和JS互调】

    1.OC中调用JS代码 公司的移动端需要加载一个现有的网页,并且要在原网页要做一些小的调整,如将网页的标题改一下加载到手机的app上,此时就可以在app的oc代码中加入JS代码来实现.如下例子,我要加 ...

  8. IO-File 文件 目录 基本操作 递归 遍历

    创建和删除 //创建文件 File file1 = new File("不存在的文件.txt");//注意,这一步并没有创建文件,只是把磁盘中的文件封装成了一个对象 System. ...

  9. Calendar( 日历)

    本节课重点了解 EasyUI 中 Canlendar(日历)组件的使用方法,这个组件不依赖于其他组件.一. 加载方式//class 加载方式<div id="box" cla ...

  10. ActiveReport 9手把手搭建环境及实战

    本文借鉴葡萄城空间产品,纯属分享,无任何营利目的 下载ActiveReports 9 专业版 打开下面的网站,点击立即下载,请您填写真实电子邮件地址,以获取ActiveReports产品试用版---系 ...