新增一個helloWorld資料夾,裡面創建main.go檔案。
package main
import "fmt"
func main() {
fmt.Println("Hello World!!")
}
ㄝ? 圖中ㄉ資料夾不符 請無視
寫完存檔後,到helloWorld資料夾裡下
$ go run main.go
這一行的效果等於以下兩行
$ go build main.go
編譯出一個執行檔
$ ./main.exe
接著執行它(但
go run
產生的執行檔是在電腦的暫存區/tmp下)
或者用Goland IDE,直接按預設快捷鍵
Ctrl + Shift + F10(for windows)
Ctrl + Shift + R(for Mac)
編譯&執行
變數宣告了就要使用, 否則會出現variable declared and not used的錯誤。
除非變數的名稱為_
var Name Type = Expression
var a int = 16
要嘛省略
型別 Type
,由Expression
決定Type
要嘛省略表達式 Expression
,變數值為Type
的初始值(零值)
初始值(零值):0, false, "", nil 等等
https://play.golang.org/p/MnmDT24cMTQ
func main() {
var a = 16
var b int
var _ = 10
fmt.Println(a, b)
}
// result:
// 16 0
短變數宣告(Short variable declarations)
Name := Expression
a := 10
宣告declare(:=)
跟 指派assign(=)
是不同的,
一次宣告多個變數,若已宣告過的變數會自動變成assign效果
https://play.golang.org/p/cy6L6tKz01n
func main() {
var b int = 123
a, b := 100, 99
c, b := 0, 1
fmt.Println(a, b, c)
}
// result:
// 100 1 0
短變數宣告 (:=) 方法簡便,
常用在宣告初始化大量、生命週期短的區域變數(就是迴圈內的i, j啦);
反之,var 則常用在明確設定型別、生命週期較長的變數。
坑A範例
https://play.golang.org/p/1aI9NdAdrQ_T
package main
import "fmt"
var a = "Hello!"
func main() {
b := 10
fmt.Println(&a, a, &b, b)
a, b := 100, 99
fmt.Println(&a, a, &b, b)
}
/* result:
0x54dc50 Hello! 0xc00002c008 10
0xc00002c048 100 0xc00002c008 99
*/
發現了嗎?
只要有 var
或:=
出現,就是宣告新的變數、挪用新的記憶體空間
所以導致全域變數a
的地址被蓋掉了
坑B範例
https://play.golang.org/p/3iAo5wIt32D
package main
import "fmt"
var i = 123 // 全域變數
func main() {
fmt.Println(&i)
i = 123
fmt.Println(&i)
i := 123 // 全新的。func區塊內的區域變數
fmt.Println(&i)
i, j := 123, 100
fmt.Println(&i, j) // 奇怪?i沒有變新的啊
}
/* 運行結果
0x11662a0
0x11662a0
0xc0000b2008
0xc0000b2008 100
*/
只要有 var
或:=
出現,就會挪用全新的記憶體空間嗎?
答案是:不一定。
程式會去查找目前最小單位的區塊內 是否已經有宣告過的變數,
沒有的話才會宣告新的。
看到有 var
會是全新的。
但看到 :=
卻是不一定,短變數宣告可以伴隨著未宣告的變數一起出現。
https://play.golang.org/p/E3xcRJjTTjx
package main
import "fmt"
var x = 123 // 全域變數
func main() {
fmt.Println(&x)
var x = 123 // 在`func區塊`。全新。
fmt.Println(&x)
// var x, y = 123, 100 // 因為x已經宣告過了,不能再用`var`。但以下卻可以
x, y := 123, 100 // 在`func區塊`。此時x是上面宣告過的區域變數,而y是新的
fmt.Println(&x, &y)
if true {
var x, y = 123, 100 // 在新區域`if區塊`。此時x跟y都是全新的。
// 可以換成短變數宣告。
fmt.Println(&x, &y)
}
fmt.Println(&x) // 脫離if區域,回到`func區塊`
}
/* 運行結果
0x11662a0
0xc000016080
0xc000016080 0xc000016088
0xc000016090 0xc000016098
0xc000016080
*/
未來會常常看到下面這種用法
connect, err := ...(server)
或者
result, err := ...
此時:=
左邊的兩個變數,都會是區域變數,
不是你外面宣告的全域變數。
另外
var
,無法用:=
常數:無法更動、無法刪除的變數
但用法跟變數var
一樣,const
後面可以接任何型別,
因為常數硬梆梆的,所以單字通常為全大寫
const PI = 3.14159
const HELLO = "Hello World"
iota
是希臘字符,在Golang中是關鍵字之一,用在宣告常數中,
效果為數字遞增,iota
本身數值從0開始,
便於工程師不用手動打數字0、1、2、3...重複且無聊的事情。
const (
A = iota // 0
B // 1
_ // 2 佔位符也會被計算
C // 3
D = iota * 0.1 // 0.4 接續前面的 iota
E // 0.5
F // 0.6
G // 0.7
)
起始值也不一定要從0開始
const (
X = iota + 100 // 100
Y // 101
Z // 102
)
也常被拿來作 左移右移(Shift Bit) 運算
const (
b1 = 1 << iota // 1 右側被塞入0個bit (2^0 二的零次方)
b2 // 2 右側被塞入1個bit (2^1 二的一次方)
b3 // 4 右側被塞入2個bit
b4 // 8
b5 // 16
)
https://play.golang.org/p/jVOzeLxu-mB
Hi 你好,
這邊這樣寫好像有點讓人誤解寫的到底是ABC的值還是iota那時候是多少?是嘛?
const (
A = iota // 0
B // 1
_ // 2 佔位符也會被計算
C // 3
D = iota * 0.1 // 0.4 接續前面的 iota
E // 5 (應該是iota 5 繼續 x 0,1) 所以應該是0.5才對
F // 6 <== 0.6
G // 7 <== 0.7
)
感謝糾正^^,已將內文更新
沒問題!謝謝你的文章^^
嗨關於坑B的部分
發現了嗎?
這裡一開始的:= 出現,反而沒有挪用新的記憶體空間
可是後來的:= 就又挪用新的記憶體空間
是不是有寫錯或是我哪裡理解錯誤的地方呢
在第一次執行a:=123的時候
記憶體位置的確從
0x53f108 變成 0xc000094018了吧
後面執行a, b := 100, 99的時候
才是都是0xc000094018
是不是有寫反呢
原先的範例的確寫反了,
已將之編排做修正,謝謝^^
沒事,繼續拜讀文章XD