文档章节

golang实践-目录结构与工具

我是大班生
 我是大班生
发布于 2016/10/18 16:38
字数 1646
阅读 83
收藏 1

原文转自自己在csdn的博客,这次只是尝试。


这个话题确实是老调重弹,但确异常重要。 老实说,用go做正式项目之前,写过scala,但那个SBT太折磨人,偶然就上了go。两者语法的差别就不说了,但入坑之后才发现水深:没有模块部署及官方的版本管理工具,会带来很多麻烦。 反复折腾了近一年,基本上形成了一点固有的模式,做一般项目还算能够简单支持。没什么特别的技术点,更多只是一点心得。


##一、目录结构##

我们的代码以rpc为主,http为辅(调用rpc,也辅助测试),基本上一个项目就按照下面这个目录结构定制。

//project directory
--src  //源代码目录,需纳入vcs
    --package1
        --package1
            --main.go   //package1编译生成的执行文件源代码
        --othersubpackage
    --package2
        --package2
		    --main.go  //这么摆放,是因为执行文件默认是[目录名]
        --othersubpackage
    --utils//公共的代码
    --vendor //第三方包目录,glide生成,可不纳入vcs
    glide.yaml  //glide生成的文件,需纳入vcs
    glide.lock  //glide生成的文件,需纳入vcs
--cfg //配置文件存放目录,需纳入vcs
    package1.yaml 
--pkg
--bin
compile.sh  //编译脚本
.bash_profile //工程环境

以上结构,适合于内部项目开发,按照项目进行统一采用glide进行管理。就版本管理工具有很多选择,考虑glide主要是:

  1. 简单,第一次用的时候半分钟搞定。只需要在src目录下,先后执行glide init、glide install;定期用一下glide up,自动升级第三方包。
  2. golang.org不再被墙之后,基本能一次性更新。 但要特别注意,glide在使用的时候,对tag标签的规则有一定的要求,需要遵循 Semantic Versions 的规则。之前,个别知名的库不是很规范,经常在up的时候反而是老版本,但现在这种问题很少。 安装glide也很简单,因为用的macos,所以brew install glide 就很容易搞定。 当然,github上面很多也用godep,如果有精力,可以投入时间去熟悉、使用。

编译脚本 compile.sh是一个代码编译脚本,偶尔进行一下维护就好。

#清理
go clean all
#需要维护的包,只需要列出含有执行文件的包名
MYSERVICE=("package1" "package2")
#生成本地运行文件
 for SERVER in ${MYSERVICE[*]}
        do
        echo "正在编译服务$SERVER mac版"
        go install $SERVER/...
 done
#生成linux运行文件
 for SERVER in ${MYSERVICE[*]}
        do
        echo "正在编译服务$SERVER linux版"
       GOOS=linux GOARCH=amd64 go install $SERVER/...
 done

环境变量设置 .bash_profile是工程的环境变量设置。最初是为了避免不同项目在go get的时候,将该项目的包放入其他项目中【后来用了glide不存在这个问题,但这个习惯继续沿用】。我们采用不同项目的根目录下增加了这个文件。每次进相关项目的时候,加载一下即可。加载很简单:

source .bash_profile //或者
. .bash_profile

暂时该文件的内容很少,最核心的就是gopath的设置,这个将直接影响到go get的包存放地址。

export GOPATH=/Users/xx/dev/code/project

采用这个方式,如果要想不同项目用不同的go版本,也就easy了。

程序配置文件 项目实施过程中,除了用环境变量,先后用了ini、json、yaml三种格式文件作为程序的启动参数配置文件。 json做配置很简单,直接读即可。可以封装一个方法:

func ReadJson(filename string, def interface{}) error {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("ReadJson failed: %T %v", def, err)
	}
	if err = json.Unmarshal(data, def); err != nil {
		return fmt.Errorf("ReadJson failed: %T %v %v", def, filename, err)
	}
	return nil
}

最大不足在于无法为配置写描述,这在使用的时候要配合第三方文档。

ini作为配置文件,其实很强悍,可以用第三方库config来调用,支持很全:

  • [x] 可以有备注
  • [x] 可以分章节
  • [x] 可以在值中用变量
  • [ ] idea对ini没有好的编写插件。

最终是因为用glide才开始了解yaml,发现作为配置文件,有很明显的优势:

  • 写作方式类似于ini,相对于json能备注,不用写括号
  • 支持数组,缩进表示内嵌struct
  • ide有yaml编写插件,能够简单的颜色、缩进显示。
  • 绝大部分go代码,都采用yaml,本来就有技术需要。
  • 包的支持不错gopkg.in/yaml.v2,使用简单。配置文件不正确情况下,只影响对应属性的赋值。从而可以用初始值对象,健壮性提升。 这一点,可以补充一段代码来描述:
package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
)

type T struct {
	F int `yaml:"a,omitempty"`
	B []string
	C int
	D float64
}

func main() {
	var t T
	t.D = 9                                                        //提供一个初始值,判定出错情况下是否改变
	err := yaml.Unmarshal([]byte("a: 1\nb: 12 \nc: 3 \nd: a"), &t) //输入条件中,b和d的值是错误的
	fmt.Println(err)
	fmt.Println(t)
	//output:
	//yaml: unmarshal errors:
	//line 2: cannot unmarshal !!int `12` into []string
	//line 4: cannot unmarshal !!str `a` into float64
	//{1 [] 3 9}   <--可以看出,a、c的识别没有错,t.D依然为原始值。
}

##二、开发工具## 对于基本没有专属开发工具的语言而言,go的开发环境反而百花齐放。我自己先后用过LiteIDE、subtext line 3 、atom、eclipse、idea。这几个工具各有特长

  • LiteIDE 功能单一,容易上手,适合新人。
  • Sublime Text 、atom 资源占用少,前者的秒开太无敌。团队中,曾经搞c++、c服务端的玩过。自己用惯IDE,不是很适应同一个语言要装n个插件。
  • eclipse,15年的时候很不错,每次修改代码都会自动build一次,很便于查找问题。但相对于前两者,对go语言没有特别亮点的额外支持。
  • idea,这是神器,除了coding,对yaml、json的维护,写js、sql等都方便(eclpise也有)。人无我有的重构,至今还是所向披靡。

由于工程中除了go,js、sql、yaml都有涉及,实际项目中都选择的IDE。16年开始,因为插件越来越成熟,问题处理及时(晚上提交bug,早上醒来就已经搞定),现在只用idea。只是,由于go的接口实现不用显示声明,它的shift+F6有点不够强悍。 人生苦短。对于有php、python开发经历的,直接选择idea,没必要折腾其他工具。

本文转载自:http://blog.csdn.net/qq_26981997/article/details/52849812

我是大班生
粉丝 0
博文 3
码字总数 1777
作品 0
渝北
架构师
私信 提问
区块链教程Fabric1.0源代码分析链码 链码语言平台-兄弟连

Fabric 1.0源代码笔记 之 Chaincode(链码) #platforms(链码语言平台) 1、platforms概述 platforms代码集中在core/chaincode/platforms目录下。 core/chaincode/platforms目录,链码的编写...

郭子乐
2018/10/29
0
0
产品环境中 Go 语言的最佳实践

在SoundCloud,我们为客户构建了产品的API。或者说,我们主要的网站、手机客户端和手机应用是该API的第一批客户。该API背后是一个领域性的服务:SoundCloud基本上以面向服务体系结构的形式运...

oschina
2014/04/27
10.8K
12
『Go 语言学习专栏』-- 第六期

大家好,我叫谢伟,是一名程序员。 我们已经研究了: Golang 环境的搭建、设置GOPATH、GOROOT 参数,Govendor 包管理, Goland 集成开发环境 Golang 语言学习专栏 -- 第一期 Golang 的基础知...

谢小路
2018/05/12
0
0
mac下grpc(golang server + php client)实践

目前微服务这么流行,RPC框架也是百花齐放,本文讲述一下mac下grpc的开发环境搭建,其中server端使用golang,客户端使用php。 服务端 golang grpc安装 这里列出了一个参考,由于grpc在githu...

陈晓风
2018/07/01
0
0
golang中的单元测试

一般为了保证整个系统的稳定性,通常都需要编写大量的单元测试,诸如像java的junit,php的phpunit等都提供了类似的功能。golang中的testing包提供了这个测试的功能,结合go test工具搞起来就...

平凡之路
2016/07/13
29
0

没有更多内容

加载失败,请刷新页面

加载更多

老也有错?35岁程序员是一道坎,横亘在每个技术职场人的心中

随着互联网的高速发展变革,大龄恐惧症越来越多地在技术圈被人讨论。很多程序员在工作5-10年以后,都会开始思考5年、10年甚至更久以后的自己,会是怎样一种生活工作状态,以及是否会被时代抛...

我最喜欢三大框架
31分钟前
2
0
今日头条算法原理详解全集,值得收藏!

今天,算法分发已经是信息平台、搜索引擎、浏览器、社交软件等几乎所有软件的标配,但同时,算法也开始面临质疑、挑战和误解。今日头条的推荐算法,从 2012 年 9月第一版开发运行至今,已经经...

骚年锦时
43分钟前
4
0
零拷贝:用户态视角

在Linux系统越来越多的人听说过所谓的零拷贝技术,但是我经常遇到很多对这个名词没有完全理解的人。因此,我决定写一些文章,深挖这个问题,希望能揭开这个有用的特性。在这篇文章,我们从用...

凌渡
55分钟前
1
0
以太坊中文文档翻译-区块

本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读。 区块(Blocks) 区块相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独...

Tiny熊
今天
2
0
Linux 内核的一个问题

是virtio 驱动,但是没有启动 virtio-mmio virtio-mmio.0: Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.....[ 1.047924] md: ... autorun......

MtrS
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部