服务计算 第七周
Go语言CLI 命令行 Agenda实战经验
1.博客内容
在Go语言开发Agenda的过程中,遇到了很多有关Go语言的问题并且学习了很多骚操作,把这些整理了一下,作为一篇博文。由于在这次开发中架构都已经设计好了,我们只是单纯的实现函数,在此基础上稍加更改数据结构,因此本篇博文总结的知识点都很零碎,多为一些实战应用的内容。
主要包括
- 1.切片的使用:怎么样快速的访问一个元素并且快速删除?
- 2.层层嵌套:用什么技巧减少嵌套结构,增加代码的可读性?
- 3.文件读写更新覆盖
2切片使用
2.1查找元素
一般的语言都会有关于查找的函数,尤其是数组(此处为切片,下同),能够快速的查找到某元素是否在数组中,但是遗憾的是,在Go语言中,我并没能找到这样的方法,因此,只能够用最原始的方法,即遍历查找,但是能够使用一些小技巧,让查找变得容易,当然了,这个方法是后面快速删除的前驱步骤!
for i, meeting := range meetings {
stmt
}
使用这种方法主要有几个优点:
- 1.相比较
C
语言的遍历模式来说,更加的快,类似于迭代器。- 2.能够直接将需要的元素以引用的方式取出来,更加的高效,而且写出的代码没有繁琐的括号,更加的简洁。
2.2快速删除元素
有什么正常删除的方法吗?答案是没有。让人疑惑的是,为什么Go语言只能够用最愚蠢的方法,人工删除元素。那么有什么简单的方法能够让手工不那么繁琐呢?(虽然在原理上并没有什么改变)当然是有的,就是运用
append
方法。
当我们要删除第i
个元素的时候,只需要用下面的语句:
array = append(array[:i], array[i+1:]...)
从原理上看,还是愚蠢的拼接,但是写法已经非常精炼了!
当然最关键的是,当我们要删除元素的时候,都是先找到他,然后删除,那么如果用我们上面的遍历方法,第一个参数i
即是当前元素meeting
在队列中的位置。
两种方法结合起来用,非常方便!
2.3只提取切片,不获得位置(常用于查询)
在进行一般的遍历操作的时候,我们可能并不会使用到位置,这个时候,如果编译,就会产生错误:变量声明且未使用。如何避免这样的情况?只需要使用一件非常简单的小技巧:
_
,例如:
for _, meeting := range meetings {
stmt
}
使用一个
_
来代替计数值
2.4注意修改——只能使用角标访问
在经过了很多坑之后,我发现了一件很坑爹的事情——通过这种方法来遍历,得到的并不是切片本身,而是一个复制值,因此,更改得到的元素,只能够通过角标来访问,并且注意,更改了之后,并不会对得到的元素同步!!!
3.减少连环嵌套——使用continue
在这道题里,会发现有很多连环嵌套的结构,尤其是在进行与会人删除及会议信息更新的时候,常常需要用到5、6层
for
及if
嵌套,那么有什么方法可以减少嵌套呢?实际上,凡是运用到等价判断
的if
语句,都可以通过continue
来减少嵌套:
//连环嵌套
for conditon {
if a == b {
stmt....
}
}
//使用condition减少嵌套
for conditon {
if a != b {
continue
}
stmt
}
在上层结构中,嵌套了两层,而在下面的结构中,只需要一层嵌套,并且对于增加的开销,实际上非常小!
4.文件读写更新覆盖
为了安全性的保障,一般都会实行文件读写,指令执行的时候读取文件,执行结束后存入文件,但是在一些功能实现的时候可能会调用到其他的函数,例如,在会议系统中:如果要删除一个用户,那么需要三步操作:
- 1、删除自己主持的所有会议
- 2、退出自己参加的所有会议
- 3、注销用户
可以发现,在这三步里,第一步与第二步是可以通过调用其他的函数来实现的,但是实际上,在每一个函数中都会涉及到文件读写,那么就会出现文件覆盖的问题。
试想,一个函数调用另一个函数
func_1 (param ) {
a = READ_FILE (A)
func_2()
WRITE_FILE(a)
}
在这个函数中,如果
func_2
同样读取了文件A
,并修改结果并存了回去,那么这个修改是否有效呢?我们来按照思路理一下:在func_1
中,读取A
,存储在a
中,假设为1
;接着,在func_2
中,同样读取了文件A
,并把值修改为2
,存回文件。执行完成后,回到func_1
,接着把a
存回文件A
,此时值被覆盖回了原有值。
因此,在功能函数编写的时候,最好不要引用别的函数,如果引用了别的功能函数(且会修改原有值),那么一定不能在修改过后再次存储。当然了,我们也可以通过设置一个dirty_bit
来跟踪文件修改情况。(但是确实很麻烦)