安裝 Golang
在 http://golang.org/dl/ 可以下載到 Golang。安裝文檔:http://golang.org/doc/install。
Hello Go
我們先創(chuàng)建一個文件 hello.go:
復制代碼 代碼如下:
package main
import "fmt"
func main() {
fmt.Printf("hello Golang\n");
}
執(zhí)行此程序:
復制代碼 代碼如下:
go run hello.go
包
Golang 程序由包(packages)組成,程序從 main 包開始運行:
復制代碼 代碼如下:
package main
此語句表示此文件屬于 main 包(多個源文件可以屬于同一個包)。import 語句后接上包所在的路徑(被叫做包路徑或導入路徑),一個目錄中放置一個包,通常的做法是,目錄名和包名相同:
復制代碼 代碼如下:
import (
"fmt"
"math/rand"
)
這里的 “fmt” 和 “math/rand” 為包路徑(導入路徑)。上面的 import 語句也可以這樣寫:
復制代碼 代碼如下:
import "fmt"
import "math/rand"
我們導入了包之后,就可以通過 “包名.name” 來引用導出的 name 了,例如:
復制代碼 代碼如下:
import "fmt"
// fmt 包導出了 Printf
fmt.Printf("hello Golang\n");
在 Golang 中,一個名字如果首字母大寫則表示此名字被導出。
函數
復制代碼 代碼如下:
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
需要注意的就是,變量名在類型之前,這和很多語言都不一樣。另外 x int, y int 也可以寫為 x, y int:
復制代碼 代碼如下:
func add(x, y int) int {
return x + y
}
函數可以返回多個值:
復制代碼 代碼如下:
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
返回值可以被指定變量名,并且像變量一樣使用:
復制代碼 代碼如下:
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
可以看到 split 函數直接使用 return 語句而不用帶參數。
變量
變量的聲明使用 var 語句:
復制代碼 代碼如下:
var i int
var c, python, java bool
變量在聲明時可以進行初始化:
復制代碼 代碼如下:
var x, y int = 1, 2
var i, j = true, "hello"
我們看到,初始化時可以指定也可以不指定變量類型。
按照 Golang 的語法,在函數外的任何結構(construct)都通過一個關鍵字開始,例如變量使用 var 關鍵字開始,函數使用 func 關鍵字開始。在函數內,變量賦值可以使用 := 操作符:
復制代碼 代碼如下:
package main
func main() {
var x, y int = 1, 2
i, j := true, "hello"
}
:= 操作符左邊為變量,右邊為值。
數據類型
基本數據類型:
1.bool
2.string
3.int int8 int16 int32 int64
4.uint uint8 uint16 uint32 uint64
5.uintptr
6.byte(等價于 uint8)
7.rune(等價于 int32,用于表示一個 unicode code point)
8.float32 float64
9.complex64 complex128
類型轉換使用表達式 T(v),含義為將 v 轉換為類型 T:
復制代碼 代碼如下:
var i int = 42
var f float64 = float64(i)
i := 42
f := float64(i)
類型轉換總需要顯式的進行。
使用 const 來聲明常量:
復制代碼 代碼如下:
const Pi = 3.14
const (
Big = 1 100
Small = Big >> 99
)
控制語句
for 語句
Golang 使用(且只使用)for 來進行循環(huán)(沒有 while 語句):
復制代碼 代碼如下:
package main
func main() {
sum := 0
for i := 0; i 10; i++ {
sum += i
}
// 這種寫法等價于 C/C++ 等語言中的 while 語句
for sum 1000 {
sum += sum
}
}
區(qū)別于 C/C++ 等語言,使用 for 語句時不需要 () 并且 {} 是必須的(后面談到的 if、switch 在此語法處理上也是一樣的)。如果需要無限循環(huán),那么使用:
復制代碼 代碼如下:
for {
}
if 語句
if 語句可以在執(zhí)行條件判斷前帶一個語句(這常被叫做 if 帶上一個短語句),此語句中變量的生命周期在 if 語句結束后結束。例如:
復制代碼 代碼如下:
package main
import (
"fmt"
"math/rand"
)
func main() {
if n := rand.Intn(6); n = 2 {
fmt.Println("[0, 2]", n)
} else {
fmt.Println("[3, 5]", n)
}
// 這里開始無法使用變量 n
}
switch
復制代碼 代碼如下:
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
// switch 類似 if 可以帶上一個短語句
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
不像 C/C++ 等語言,Golang 中無需使用 break 語句來跳出 switch。另外,switch 可以沒有條件:
復制代碼 代碼如下:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() 12:
fmt.Println("Good morning!")
case t.Hour() 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
defer
一個 defer 語句能夠將一個函數調用加入一個列表中(這個函數調用被叫做 deferred 函數調用),在當前函數調用結束時調用列表中的函數。范例:
復制代碼 代碼如下:
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
deferred 函數調用按先進后出的順序執(zhí)行:
復制代碼 代碼如下:
package main
import "fmt"
func main() {
for i := 0; i 5; i++ {
// 輸出 43210
defer fmt.Print(i)
}
}
結構(structs)
結構是一個域的集合:
復制代碼 代碼如下:
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v)
}
Golang 中是存在指針的,但是指針不支持算術運算:
復制代碼 代碼如下:
p := Vertex{1, 2} // {1, 2} 為 struct literal
q := p // q 類型為 *Vertex
q.X = 2 // 直接訪問域 X
就像上面看到的,struct 的 literal 由 {} 包裹,在 struct literal 中我們可以使用 Name: 這樣的語法來為特定域設置值:
復制代碼 代碼如下:
type Vertex struct {
X, Y int
}
r := Vertex{X: 3} // 這時候 Y 為 0
new 函數
我們可以通過表達式 new(T) 分配一個被初始化為 0 且類型為 T 的值,并且返回指向此值的指針,用法如下:
復制代碼 代碼如下:
var p *T = new(T)
p := new(T)
更詳盡的例子:
復制代碼 代碼如下:
package main
import "fmt"
type Vertex struct {
X, Y int
}
func main() {
v := new(Vertex)
fmt.Println(v)
v.X, v.Y = 11, 9
fmt.Println(v)
}
數組和 slice
[n]T 在 Golang 中是一個類型(就像 *T 一樣),表示一個長度為 n 的數組其元素類型為 T。范例:
復制代碼 代碼如下:
package main
import "fmt"
func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
}
注意,數組長度無法被改變。
slice 是一個數據結構,其指向一個數組某個連續(xù)的部分。slice 用起來很像數組。[]T 為 slice 類型,其中元素類型為 T:
復制代碼 代碼如下:
package main
import "fmt"
func main() {
// 構建一個 slice
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p)
for i := 0; i len(p); i++ {
fmt.Printf("p[%d] == %d\n", i, p[i])
}
}
表達式 s[lo:hi] 用于創(chuàng)建一個 slice,新創(chuàng)建的 slice 的元素為 s 中 [lo, hi) 位置的元素。
創(chuàng)建 slice 使用 make 函數(而不是用 new 函數,因為需要設置額外的參數來控制 slice 的創(chuàng)建):
復制代碼 代碼如下:
// len(a) 為 5
a := make([]int, 5)
這里 make 函數會創(chuàng)建一個數組(其元素初始化為 0)并返回一個 slice 指向此數組。make 可以帶第三個參數,用于指定容量:
復制代碼 代碼如下:
// len(b) 為 0
// cap(b) 為 5
b := make([]int, 0, 5)
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
一個沒有值的 slice 是 nil,長度和容量都為 0。
復制代碼 代碼如下:
package main
import "fmt"
func main() {
var z []int
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil!")
}
}
range
range 被用在 for 中來迭代一個 slice 或者一個 map:
復制代碼 代碼如下:
package main
import "fmt"
var s = []int{1, 2, 3}
func main() {
for i, v := range s {
fmt.Println(i, v)
}
// 只需要值,使用 _ 忽略索引
for _, v := range s {
fmt.Println(v)
}
// 只需要索引
for i := range s {
fmt.Println(i)
}
}
map
map 用于映射 key 到 value(值)。map 可以通過 make 來創(chuàng)建(而非 new):
復制代碼 代碼如下:
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
}
map iteral 很像 struct literal:
復制代碼 代碼如下:
var m = map[string]Vertex{
// 這里 Vertex 可以省略不寫
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
使用 [] 來訪問 map 中的值,使用 delete 來刪除 map 中的值:
復制代碼 代碼如下:
m[key] = elem
elem = m[key]
delete(m, key)
如果需要檢查 map 中某 key 是否存在使用:
復制代碼 代碼如下:
elem, ok = m[key]
elem 表示 key 的值(key 不存在時,elem 為 0),ok 表示 key 是否存在。
閉包
Golang 中函數也是一個值(就像 int 值一樣),且函數可以是一個閉包。閉包是一個引用了外部變量的函數。看一個例子:
復制代碼 代碼如下:
package main
import "fmt"
func adder() func(int) int {
sum := 0
// 返回一個閉包,此閉包引用了外部變量 sum
return func(x int) int {
sum += x
return sum
}
}
func main() {
a := adder()
fmt.Println(a(9527))
}
您可能感興趣的文章:- golang分層測試之http接口測試入門教程
- golang編程入門之http請求天氣實例
- Golang極簡入門教程(四):編寫第一個項目
- Golang極簡入門教程(三):并發(fā)支持
- Golang極簡入門教程(二):方法和接口
- golang特有程序結構入門教程