服務計算 第七週
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
來跟蹤文件修改情況。(但是確實很麻煩)