寫在前面
Golang的語法足夠簡(jiǎn)單珠增,但變化很多超歌,剛接觸只需要掌握典型的用法即可,不需要知道所有的語法糖蒂教,所以代碼中并不會(huì)包含所有可能的語法形式巍举。
并發(fā)是Golang的一大主題,后續(xù)有專門的一節(jié)凝垛,并不出現(xiàn)在這一節(jié)懊悯。
還有一些『約定』:
- 可見性。Java中有private梦皮,protect炭分,public。Golang默認(rèn)采用首字母大小寫來判斷:首字母大寫的變量剑肯、方法為public捧毛,所有范圍內(nèi)可見;首字母小寫的為private让网,本文件內(nèi)可見呀忧。
- 簡(jiǎn)潔性。import引入的包以及定義的變量必須被使用溃睹,否則程序編譯不通過荐虐。因此,代碼
var p ClassA
不是一個(gè)聲明定義丸凭,而是包含了初始化,實(shí)際上內(nèi)存已經(jīng)被分配了腕铸,這一點(diǎn)很容易忽視惜犀。
下面上代碼:
//一段普通的Go語言代碼,用于go語言學(xué)習(xí),作者知米無忌于2016-11-29
//聲明包狠裹,包名和目錄的路徑一致虽界,以$GOPATH/src為根,如src/math/add.go的包為math涛菠。
// 此外莉御,如果為入口(即包含main函數(shù))則包名為main撇吞,此時(shí)可以被go build編譯為可執(zhí)行文件。
package main
//塊狀import注意:
//import必須被使用礁叔,不能import了但不用他
import (
"fmt"
"strconv"
"reflect"
)
//塊狀定義變量
var (
// int 類型包括了rune, int8, int16, int32, int64和byte, uint8, uint16, uint32, uint64牍颈。其中rune是int32的別稱,byte是uint8的別稱琅关。
myInt int
//float 包括了float32,float64
myFloat float32
myBool bool
myString string
)
//塊狀聲明常量
const (
constString = "hello world,世界"
)
// 全局單獨(dú)定義的變量
var globalDefinedVar interface{}
// 定義一個(gè)結(jié)構(gòu)體(也是類煮岁,因?yàn)間olang沒有類的概念),面向?qū)ο?type person struct {
name string
age int
}
//person 的成員函數(shù),顯式的指定p涣易,即Java中的this指針画机,python中的函數(shù)第一個(gè)參數(shù)self
func (p *person) introduceMyself() {
fmt.Println("my name is " + p.name)
fmt.Println(p.age)
}
func (p *person) shoot() {
fmt.Println("I can shoot, so I can play football.")
}
//定義一個(gè)接口
type footballPlayer interface {
shoot()
}
func main() {
////////////
// 1.變量定義
////////////
var localString string
localString = `字符串是
一對(duì)雙引號(hào)(表示單行)或反引號(hào)(表示多行)
括起來定義`
////////////
// 2.rune, byte數(shù)組,string的關(guān)系
////////////
myRune := '我'
fmt.Println(myRune)
//rune轉(zhuǎn)為string
myRuneString:= string(myRune)
fmt.Println(myRuneString)
//rune轉(zhuǎn)為字節(jié)數(shù)組
bytes:=[]byte(myRuneString)
fmt.Println(bytes)
// interface{} 類型可賦值任意類型,類似Java的Object類型
globalDefinedVar = localString
newVar := ":=是聲明并初始化的簡(jiǎn)寫形式新症,由系統(tǒng)自動(dòng)推測(cè)類型"
fmt.Println(newVar)
////////////
// 3.數(shù)組定義并初始化
////////////
myArray := [3]int{1, 2, 3}
//數(shù)組定義,默認(rèn)初始化為了5個(gè)0
var myArray2 [5]int
fmt.Println(myArray2)
fmt.Println(myArray)
////////////
// 4.slice
////////////
mySlice := []int{1, 2, 3, 4}
//從數(shù)組創(chuàng)建slice步氏,注意1:的使用方式,從第一個(gè)元素取到末尾徒爹,還可以[1:4]從第一個(gè)取到第四個(gè)(不包含)荚醒。來自于python(作者注)
mySlice2 := myArray[1:]
mySlice=append(mySlice,5,6,7)
////////////
// 5.if,else塊沒什么特殊,myBool未定義默認(rèn)為false,執(zhí)行else
////////////
if myBool {
fmt.Println("if")
} else {
fmt.Println("else")
}
////////////
// 6.for 循環(huán)
////////////
for index, value := range mySlice {
fmt.Printf("index: %d,value:%d \n", index, value)
}
for (true) {
fmt.Println("還可以這樣使用瀑焦,相當(dāng)于while(true)")
//避免無限循環(huán)腌且,直接break掉
break
}
////////////
// 7.map創(chuàng)建,刪除和使用榛瓮,range關(guān)鍵字使用
////////////
myMap := make(map[string]int)
myMap["a"] = 1
myMap["b"] = 2
myMap["c"] = 3
delete(myMap, "a")
for key, value := range myMap {
fmt.Printf("key: %s,value:%d", key, value)
}
////////////
// 8.面向?qū)ο? ////////////
// 對(duì)象初始化的兩種方式铺董,第一種返回的是指針,第二種返回的是對(duì)象禀晓。
//注意new永遠(yuǎn)返回指針
jack := new(person)
jack.name = "jack"
jack.age = 17
amy := person{"amy", 16}
jack.introduceMyself()
//證明是指針
(*jack).introduceMyself()
amy.introduceMyself()
//拋異常 invalid indirect of amy (type person)
//(*amy).introduceMyself()
fmt.Println(reflect.TypeOf(jack))
fmt.Println(reflect.TypeOf(amy))
////////////
// 9.接口使用
////////////
//接口的賦值精续,可以看出來不需要jack的person類實(shí)現(xiàn)該接口就可以實(shí)現(xiàn),只需要擁有接口所需的功能即可粹懒。
var footballPlayer1 = jack
footballPlayer1.shoot()
//函數(shù)調(diào)用重付,可以多返回值
myString = "golang is awesome"
myRet1, myRet2 := receive2Return2(myString, myInt)
fmt.Println(myRet1, myRet2)
////////////
// 10.異常處理
////////////
//錯(cuò)誤處理,調(diào)用了一個(gè)拋異常的方法
malfunction()
//兩個(gè)知識(shí)點(diǎn):
//1.recover會(huì)收集到由調(diào)用棧中的panic拋出的異常信息
//2.defer的執(zhí)行時(shí)機(jī)是執(zhí)行defer的函數(shù)退出的時(shí)候凫乖,類似于java中的finally确垫,但是不需要把一大段代碼用大括號(hào)包圍,這樣代碼層次減少了帽芽。
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
//每個(gè)定義過的變量和常量都要被使用删掀,不允許垃圾存在,這里做個(gè)打印
fmt.Println(myBool, myFloat,constString,mySlice2)
}
func receive2Return2(param1 string, param2 int) (ret1 string, ret2 int) {
fmt.Println("param1:" + param1)
fmt.Println("param2:" + strconv.Itoa(param2))
return "returned " + param1, param2 + 1
}
func malfunction() {
panic("some thing went wrong!")
}