2012年Go语言第一个正式版本至今已经历时6年,因其优秀的性能,简洁的并发以及高效的编译等优势市场份额逐步增多,越来越多的工程实践开始选用Go语言作为基础编程语言,其生态社区也逐步发展成型,下文将从零开始构建一个Go Project。
一、Go 开发环境配置
以mac os为例,简单的配置一下Go开发环境。Step1: 安装sdk
方式1:下载 go mac pkg文件进行软件包 安装
方式2:通过homebrew 管理软件包
homebrew于mac如rpm包于linux,即mac下的软件包管理程序。可以通过如下命令安装homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
使用homebrew管理go sdk:
- brew install go 安装
- brew uninstall go 卸载
Step2: 配置环境变量
个人一直使用oh my zsh, 直接编辑用户目录下的.zshrc文件即可,bash用户可以直接修改~/.bashrc。 下图为个人的环境配置:Step3: IDE配置
永恒的信念:工欲善其事,必先利其器 目前主流的编辑器都支持了Go,比如vim,sublime,vscode,atom,如何选择完全看个人意愿了,我一直在用的是Jetbrains的 IDEA Go插件(喜欢完备特性的可以使用同系GoLand),该插件官方的说法是cover了GoLand所有特性。 直接打开Preference->Plugins安装Go插件即可二、Go 工程实践
下文将重点讲述如何以工程化标准实践为要求建设Go工程了解Go的workspace
workspace即工作空间,不同到编程语言乃至不同到IDE对于工作空间都有不同的设计理念(可以参考eclipse与IDEA工作空间的设计理念),以Java系IDE idea为例其工作空间叫Project,一个project会对应一套工程配置比如copyright,code format, and other config,比如多个项目可能使用不同的配置,那么这个时候就可以从工作空间纬度进行隔离。 而Go的设计很巧妙,其工作空间只有一个,下面引述官方doc的两段描述:- Go programmers typically keep all their Go code in a single workspace.
- A workspace contains many version control repositories (managed by Git, for example).
-
srccontains Go source files. -
pkgcontains package objects -
bincontains executable commands.
使用 go get xxx下载的源码会自动到该目录下bin目录,可执行二进制文件
这样做还有一个好处,当你多个代码仓库使用不同的账号授权时候可以按照目录进行配置,比如同时使用github与gitlab可以根据仓库目录进行gitconfig配置不同的User。
创建第一个Project
首先,我们按照Go推荐的做法完成了workspace的划分,然后开始一个git项目,以我测试的demo为例,假设叫cool.go。- doc.go Go package的doc,用来生成go package document,源码如下:
/*
ecs OpenApi demo,use aliyun ecs sdk manage ecs, this package will provide you function list as follows:
DescribeInstances, query your account ecs.
CreateInstance, create a ecs vm with specified params.
*/
package ecsproxy
使用 ``go doc `` 查看package document - ecsproxy.go 核心代码,该demo中主要封装ecs sdk操作ecs OpenAPI,源码如下:
package ecsproxy
import (
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"fmt"
)
//common init client
func initClient() (*ecs.Client, error) {
ecsClient, err := ecs.NewClientWithAccessKey(
"cn-shanghai",
"",
"")
if err != nil {
panic(err)
}
return ecsClient, err
}
func describeInstance() {
ecsClient, err := initClient()
request := ecs.CreateDescribeInstancesRequest()
request.PageSize = "10"
response, err := ecsClient.DescribeInstances(request)
if err != nil {
panic(err)
}
fmt.Print(response.Instances)
}
func createInstance() string {
ecsClient, err := initClient()
request := ecs.CreateCreateInstanceRequest()
request.InstanceType = "ecs.n1.tiny"
request.KeyPairName = "demo"
var disks *[]ecs.CreateInstanceDataDisk
var disk1 ecs.CreateInstanceDataDisk
disk1.Size = "20"
disk1.DeleteWithInstance = "true"
disk1.Category = "cloud"
request.DataDisk = disks
response, err :=
ecsClient.CreateInstance(request)
if err != nil {
panic(err)
}
fmt.Print(response.InstanceId)
return response.InstanceId
}
- ecsproxy_test.go ecsproxy.go UT,源码如下:
package ecsproxy
import (
"testing"
)
func TestDescribeInstance(t *testing.T) {
describeInstance()
}
运行ut,结果如下: