golang 雜記 - block, for, switch
block 相關雜記
Block
與c#不同,當子block內用的變數與外部block變數名稱一致時,內部的變數會遮蔽(shadow)外部區塊建立的變數。
1 | func main(){ |
與C#比較,C#的子block基本就不能命名的跟外部的變數名稱一樣,所以參考的還是同一個記憶體位址。
1 | public class Program |
所以golang在宣告相同變數的時候基本是產了兩個不同的記憶體位置來存儲。同時也說明:=
的宣告式在程式碼閱讀上在一些情景並不是很適合。
在比較一段程式碼:
1 | func main(){ |
這邊的x
在if block裡面就不是在宣告一個,而是拿上層block的x
;所以站在閱讀性上需要特別注意這點,避免內外層宣告相同名稱變數,在C#這邊編譯器會檢查並且返回編譯失敗,在Go則是合法的。
甚至包括外部引入的package也可以遮蔽
1 | func main(){ |
但所幸在golang也有提供工具可以提早檢查lint,可參考
vet
可是關鍵字的遮蔽連lint都檢查不到,要特別注意
1 | fmt.Println(true) |
for
golang沒有while, while do,取而代之都是以for操作。
for-range
1 | evenVals := []int{1,3,5,7,9} |
特別注意的是for-range
所取得的value是call by value的,對其值的更改不會影響到原有的結構體。
另外for-range
在處理字串時golang自己做了一些特別的操作,上篇文說到字串是byte陣列組成,但在做for-range
時的對象並不是[]byte,而是[]rune。
1 | func main() { |
switch
跟大多數語言差不多,差別在複數case要做同一個處理時,用,
分開condition而不是多個case。
case block沒有內容就啥都不處理,然後有個空switch可以不放要判斷的變數,不過大多數情況這樣可讀性不太高,慎用。
1 | func main() { |
golang 雜記 - block, for, switch