当前位置: 首页 > 编程日记 > 正文

Go-技篇第一 技巧杂烩

Go-技篇第一 技巧杂烩

一句话技巧

  • 把你面向对象的大脑扔到家里吧,去拥抱接口。@mikegehard
  • 学习如何使用Go的方式做事,不要把别的的编程风格强行用在Go里面。@DrNic
  • 多用接口总比少用好。@evanphx
  • 拥抱这种简洁、并行、工整的语言。@francesc
  • 阅读官网golang.org上所有的文档,真是棒呆了。@vbatts
  • 别忘了用gofmt。@darkhelmetlive
  • 多读源代码。@DrNic
  • 学习工具和组件,然后创造你自己的!码代码和学代码一样对成功必不可少。@coreyprak

引入package的多种方式

有几种非常规方式来引入包(package)。接下来我会使用fmt来作为例子:

  • import format "fmt" - 为fmt创造一个别名。把代码中所有使用到fmt的内容用format.代替fmt.
  • import . "fmt" - 允许包内的内容不加fmt前缀而被被直接引用
  • import _ "fmt" - 阻止编译器为引入fmt却不使用里面的内容做引发的警告,执行package中的初始化函数。提醒一句,在这种情况下fmt是不可调用的

看这篇博客来了解更多细节。

Goimports

命令goimports可以更新您的Go导入行,添加缺少的行,并删除未引用的引导行。

它拥有和gofmt(插入式替换)相同的能力,但是goimports额外增加了修复imports的功能。

组织

Go是一种相对来说易学习的编程语言,但对于开发者来说,起初接触这门语言最困难的事情就是如何组织代码。scaffolding是人们喜欢Rails的原因之一,它可以给新晋的开发者清晰的方向,让他们明白在哪里插入代码,应该遵循怎样的编程风格。

作为扩展,Go使用go fmt这样的工具来提供开发者相同的功能。同样地,Go的编译器非常严格,它不会去编译没有使用的变量,或者没有使用的import声明。

自定义构造函数

我经常听到别人问,“我什么时候应该使用像NewJob这样的自定义构造函数?”,我的回答是“大多数情形下你没必要这么做”。然而,当你需要在初始化的时候就设置值,且你有一些默认值的时候,这就最好使用一个构造函数。在这个例子中,构造函数就比较有意义了,因此我们用如下的代码可以构建一个默认的logger:

把代码分解到不同的package中

参考这篇博客重构Go代码,第一部分就讲了package的组织。

以工程Gobot为例,它可以被分割为一个核心package和一些其他package。gobot的开发者们准备每个部分放在自己的package里。经过讨论,他们选择把所有的官方库放在同一个repository下,让import路径变得干净而富有逻辑。

所以,他们不打算把路径设置为:

github.com/hybridgroup/gobot
github.com/hybridgroup/gobot-sphero
github.com/hybridgroup/gobot-...

而是设置为

github.com/hybridgroup/gobot
github.com/hybridgroup/gobot/sphero
github.com/hybridgroup/gobot/...

现在package的名字不再是冗长的gobot-sphero,而变成了简要的sphero。

集合(Sets)

在其他的程序语言中,经常会有一种数据结构叫做sets,它允许把元素存入,但是不允许重复。Go并不直接支持这种结构,但是这个结构在Go里面的实现并不困难。

// UniqStr returns a copy if the passed slice with only unique string results.
func UniqStr(col []string) []string {
m := map[string]struct{}{}
for _, v := range col {
if _, ok := m[v]; !ok {
m[v] = struct{}{}
}
}
list := make([]string, len(m))
i := 0
for v := range m {
list[i] = v
i++
}
return list
}

Playground链接

在这里,我会使用一些非常有意思的花招。首先,对空结构的映射:

m := map[string]struct{}{}

我们创建了一个map,这可以确保key是独一无二的,而相关联的value其实是我们不关心的。
我们当然可以使用:

m := map[string]bool{}

但是,使用空结构体可以达到同样的效率,同时不会占用额外的内存。

第二个花招的意味更为深远:

if _, ok := m[v]; !ok {
m[v] = struct{}{}
}

这里做的事情就是确认map m中的某个值是否存在,而不关心value本身。如果发现没有对应的值,就去加一个。当然,不去验证直接加好像也没有什么区别。

一旦我们拥有了一个充满独一无二key的map以后,就可以把他们放到一个切片里,返回结果了。

这里有一段测试代码,正如你所见,这里使用了一个符合Go语言单元测试风格的表格测试:

func TestUniqStr(t *testing.T) {
data := []struct{ in, out []string }{
{[]string{}, []string{}},
{[]string{"", "", ""}, []string{""}},
{[]string{"a", "a"}, []string{"a"}},
{[]string{"a", "b", "a"}, []string{"a", "b"}},
{[]string{"a", "b", "a", "b"}, []string{"a", "b"}},
{[]string{"a", "b", "b", "a", "b"}, []string{"a", "b"}},
{[]string{"a", "a", "b", "b", "a", "b"}, []string{"a", "b"}},
{[]string{"a", "b", "c", "a", "b", "c"}, []string{"a", "b", "c"}},
}
for _, exp := range data {
res := UniqStr(exp.in)
if !reflect.DeepEqual(res, exp.out) {
t.Fatalf("%q didn't match %q\n", res, exp.out)
}
}
}

经过测试发现,并非每次都能够成功,而是有概率的。因为map是使用hashmap实现的,使用range进行遍历的时候,其遍历顺序和字符串的内容没有必然联系,因此此test有可能失败。在进行DeapEqual比对的时候,可能会爆出类似于["b" "c" "a"] didn't match ["a" "b" "c"]的错误。当然,在Playground中,每次执行的上下文环境一模一样,因此这里的test是总能通过的。

依赖包管理

很遗憾,Go语言官方并不提供依赖包管理系统。这很可能是因为go语言植根于C语言的文化,因此它没有办法引入特定版本的包。

这会带来一些严重的问题:

  1. 当多个开发者共同维护一个项目时,不同开发者的依赖版本可能不同。
  2. 依赖也会有他们自身的依赖,所以很难确保所有的依赖都使用同一个版本。
  3. 你的多个项目基于了同一个依赖的不同版本。

对于最后一种情形,可以通过搭建一个_持续集成环境(Continuousintegration)来解决,但是前两者就相对困难。

package main
import (
"log"
"os"
)
type Job struct {
Command string
*log.Logger
}
func NewJob(command string) *Job {
return &Job{command, log.New(os.Stderr, "Job: ", log.Ldate)}
}
func main() {
NewJob("demo").Print("starting now...")
}

转载于:https://www.cnblogs.com/zhangboyu/p/0b5b545483b05ba60c4ac49ab65a81fd.html

相关文章:

Visual Studio 2008 到底有多强?漫画告诉你 !

插入数据需要无数个SQL语句支持,而现在,你只需要有一个强大的LinQ巴士,就直接一次性全搞定,方便快捷 " 强大的中转站,帮你解决额外的问题,数据传输选择最优路径,完成工作。数据给了WCF&a…

使用c#生成高品质小空间的缩略图

dot自带的生成缩略图的方法是Bitmap.GetThumbnailImage这个方法生成的缩略图不够清晰,一般我们会使用Graphics高质量插值发生成清晰的缩略图,这时候大小会不尽人意,怎么办?我们可以使用jpeg压缩的方法压缩一下图片,这样…

将Project的内容导出成单独的XPO文件

AX跟VSS整合的版本管理可以通过创建知识库将当前层的代码全部签入到VSS中,但是如果不是一个团队开发solution,而是针对客户的需求随时做得一些小改动,一般都希望以Project的形式组织代码和发布代码。AX与VSS的整合没有提供一种方法可以将一个…

.Net Core MVC初学习

.net core已经出来很长一段时间了,没有很好的学习过,现在工作不那么忙了,参考官方文档,在这里记录自己的学习过程! ASP.NET Core 是一个跨平台的高性能开源框架,用于生成基于云且连接 Internet 的新式应用程…

编译原理考点复习

名词填空、名词解释、解答题: 文法是什么?文法、句子、句型、确定有穷自动机(DFA)、非确定有穷自动机(NFA)的定义?编译过程主要有哪些功能模块?有什么辅助模块(表格管理…

网络工程师如何才能实现职位晋升

一、如何在公司得到攀升的机会?如果不想保持低月薪,就运用你的技术积极参与公司的业务发展从最近我们公司招生来看,一个很明显的问题阴魂不散的笼罩在“网络工程师”这个行业。问题的根本是对网络工程师职业前途的严重误解。很多人认为目前的…

Linux中/etc/resolv.conf文件简析

https://blog.csdn.net/lcr_happy/article/details/54867510转载于:https://www.cnblogs.com/answercard/p/10354514.html

第二章 Servlet核心技术 实训二

question.html <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>简单测试</title> </head> <body> <p>请回答下面的问题&#xff1a;</p> <form action"simpletest.do"meth…

BZOJ 4025 二分图

题目大意 给定一个\(n\)个点, \(m\)条边的无向图, 每条边在一定时间范围内存在. 要你判断每个时间点这张图是否为二分图.\(n \le 10^5\)\(m \le 2 \times 10^5\) Solution 我们考虑一个合法的二分图有什么性质: 图中不存在奇环, 即环上边数(点数)为奇数的环. 考虑如何判断每个时…

javascript对象之window对象详解

frames 表示当前窗口中所有frame对象的数组 status 表示浏览器的状态行信息 defaultstatus 表示浏览器的状态行信息 history 表示当前窗口的历史记录,这可以引用在网页导航中 closed 表示当前窗口是否关闭的逻辑值 document 表示当前窗口中显示的当前文档对象 location 表示当前…

Wsus简单笔记

一&#xff1a;安装前的要求1&#xff1a;iis6.0以上&#xff0c;bits、Asp.net2.02:sql20053:Microsoft Management Console 3.04:microsof report viewer redistributable 20055&#xff1a;ntsf分区二&#xff1a;安装1&#xff1a;过程比较简单&#xff0c;注意设置本地补丁…

机器学习-Sklearn

Scikit learn 也简称 sklearn, 是机器学习领域当中最知名的 python 模块之一. Sklearn 包含了很多种机器学习的方式:Classification 分类 Regression 回归 Clustering 非监督分类 Dimensionality reduction 数据降维 Model Selection 模型选择 Preprocessing 数据预处理 我们总…

[翻译]自动维护索引重新生成组织的SQL批处理语句

脚本来自《Inside Server 2005 T-SQL Programming》 SET NOCOUNT ON;DECLARE objectid int;DECLARE indexid int;DECLARE partitioncount bigint;DECLARE schemaname nvarchar(258);DECLARE objectname nvarchar(258);DECLARE indexname nvarchar(258);DECLARE partitionnum bi…

DTrace memory leak 内存泄露

http://blog.sina.com.cn/s/blog_538040b70100eecn.html如下程序用于跟踪&#xff0c;在分配和回收都会触发探针 #!/usr/sbin/dtrace -s pid$target:libc:malloc:entry{ self->trace 1; self->size arg0;}pid$target:libc:malloc:return/self->trace 1/{ …

Spark的安装和使用

Spark2.1.0入门&#xff1a;Spark的安装和使用 Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0(2.7.1)/Ubuntu14.04(16.04) 手把手教你在VirtualBox中与主机共享文件夹

SQL Server 2005系列教学(6) 多表操作及子查询

多表查询&#xff1b;<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />人事表&#xff1a; 公司表&#xff1a;姓名性别年龄姓名公司地址张三男25李四女25张三新…

(点)分治学习笔记

哗我看了一下好像没有很详细专门讲分治的blog&#xff1f;那就主要先学一下点分治吧&#xff0c;其他的……等我记得把C一本通带到机房来再说吧先咕着啦 写在前面 刷题进度 入门题&#xff08;0/3&#xff09; 好题(0/9) 问题解决进度 Q1 Q2 正文 淀粉质 点分治 点分治就是在一…

十五个步骤收获学习的习惯

"真正的发现的航程&#xff0c;并非是在寻找新的土地,而且用新的视界去寻找"--普鲁斯特 "智慧日进者方值得尊敬。"-林肯 "我从不让我在学校所学的干扰我的教育"-马克吐温 如果公立学校尚未摧残你的灵魂&#xff0c;那么学习是一项极佳的活动。它…

熟悉scala命令,scala语言运行超级素数和猴子大王

实验目的 在Linux操作系统中安装Scala输入“scala”命令&#xff0c;熟悉地运行Scala解释器scala语言运行超级素数和猴子大王实验仪器 Virtualbox管理器 实验框图&#xff08;电路图/流程图&#xff09; 在Windows中使用VirtualBox安装Ubuntu&#xff0c;安装好scala后&#xf…

安装mayavi和VTK库的血泪史

一开始安装VTK库是从官网上下载&#xff0c;但是怎么都找不到whl文件&#xff0c;只有exe文件&#xff08;vtkpython-7.1.1-Windows-64bit.exe&#xff09;。下载安装之后再PyCharm中import vtk出错。当时认为是文件出错。后来在一篇博客&#xff08;Python下VTK 编程 - lj6952…

Python LEGB (Local, Enclosing, Global, Build in) 规则

1 Local 一个函数定义了一个 local 作用域; PyFrameObject 中的 f_local 属性2 Global 一个 module 定义了一个 global 作用域; PyFrameObject 中的 f_global 属性.3 BuiltIn open, dir 的作用域等等, python 最顶层的作用…

图解DotNet框架系列

图解.Net框架系列(索引贴) (声明:本系列已完成,故索引帖重发) 众所周知,DotNet框架是非常庞大的,光项目创建时的种类就有WPF,WCF,WF这三种最新的技术,还有以前的Web,WinForm,Service,Mobile等等. 这么复杂和庞大的框架,用文字来描述是远远不够的,所以我准备写一系列图文并茂的文…

【Linux基础】文件处理实例

1.文件拆分 //每4000行拆分一个文件 split -l 4000 epms_t_ep_fx_stl_xy_20190129.dat 2.行处理 //查找第二列为711611且第三列为711100记录&#xff0c;打印行号和整行数据 awk -F ‘^C’ {if ($3711100 && $2711611) print NR,$0 } epms_t_ep_fx_stl_xy_20190229.d…

scala语言运行递归“分鱼”程序

A、B、C、D、E 五人在某天夜里合伙去捕鱼&#xff0c;到第二天凌晨时都疲惫不堪&#xff0c;于是各自找地方睡觉。 日上三杆&#xff0c;A 第一个醒来&#xff0c;他将鱼分为五份&#xff0c;把多余的一条鱼扔掉&#xff0c;拿走自己的一份。 B 第二个醒来&#xff0c;也将鱼分…

smarty_modifier_truncate,无或者有md_substr的情况下都能正确截取字符串的php函数,可用于smarty。...

smarty_modifier_truncate,无或者有md_substr的情况下都能正确截取字符串的php函数&#xff0c;可用于smarty。function smarty_modifier_truncate($string, $length 80, $etc ..., $codeutf8, $mbtrue) { if ($length 0) return $string; if(function_exists("mb_subs…

java基础小总结(2)

Day07&#xff1a; 1.如果局部变量和全局变量都有相同的数据类型和变量名&#xff0c;先调用局部变量&#xff0c;实现就近原则&#xff1b; 2.匿名对象由于局限性的原因&#xff0c;一般只调用一次&#xff0c;且只是当作为实际参数传递的时候使用&#xff1b; 3.面向对象语言…

Wireshark实验HTTP

在 Wireshark 实验入门里&#xff0c;我们已经初步使用了 Wireshark 包嗅探器&#xff0c;我们现在可以操作 Wireshark 来查看网络协议。在这个实验中&#xff0c;我们会探索 HTTP 协议的几个方面&#xff1a;基本的 GET/response 交互&#xff0c;HTTP 消息格式&#xff0c;检…

2、安装ICS(Internet Component Suite)控件

下载完成后解压到你的指写目录&#xff01;1、在library里加入ICS->Delphi->Vc32目录。2、从File->Open中打开ICS->Delphi->Vc32->IcsDel110.dproj文件。(文件名在其它Delphi版本略有不同)3、在项目管理器中&#xff0c;右键IcsDel110.bpl选择Build和Install…

定制CE系统随笔-续1

更改用户界面颜色[HKEY_LOCAL_MACHINE\SYSTEM\GWE] "SysColor"hex: 00,00,00,00, 3A,6E,A5,00, 00,00,00,00, 00,00,00,00,\ EF,EB,DE,00, FF,FF,FF,00, 00,00,00,00, 00,00,00,00,\ 00,00,00,00, FF,F…

安装包安全测试

主要说明以下内容&#xff1a;1、能否反编译代码2、安装包是否签名3、完整性校验4、权限设置检查反编译代码&#xff1a;移动应用发布出去后最终用户获得的是一个程序安装包&#xff0c;我们需要关注的是用户能否从这个安装包中获取项目的源代码&#xff0c;从安全方面考虑&…