Go語言程序基礎(chǔ)
Go語言程序基礎(chǔ)
import "fmt" ??//fmt包中提供格式化,輸出,輸入的函數(shù)。
注意事項:
①Go源文件以"go”為擴(kuò)展名。
②Go應(yīng)用程序的執(zhí)行入口是main()函數(shù)。
③Go語言嚴(yán)格區(qū)分大小寫。
④Go方法由一條條語句構(gòu)成,每個語句后不需要分號(Go語言會在每行后自動加分號)
⑤Go編譯器是一行行進(jìn)行編譯的,一行只能寫一條語句,否則報錯。
轉(zhuǎn)義符:
①\t:表示一個制表符,通常使用它可以排版。
②\n:換行符
③\\:一個\
④\":一個"
⑤\r:一個回車
注釋:
①行注釋//
②塊注釋/**/,不可嵌套
縮進(jìn):
①Shift+tab:整體左移;再tab:右移;
②用gofmt進(jìn)行格式化;
?

③運算符兩邊習(xí)慣性各加一個空格。
④代碼風(fēng)格:
?

⑤一行最長不超過80個字符,超過的請使用換行展示。
?
Golang 中文網(wǎng)在線標(biāo)準(zhǔn)庫文檔:https://studygolang.com/pkgdoc
Dos常用指令:
Dos:Disk Operating System磁盤操作系統(tǒng)
清屏:cls
推出dos:exit
目錄操作指令:
查看目錄:D:\>dir
切換到F盤:D:\>cd ?/d ?f:
切換到當(dāng)前盤的其他目錄下(相對路徑、絕對路徑):
>cd d:\test100\abc100
>cd abc100
切換到上一級:>cd ..
切換到根目錄:>cd \
新建一個目錄:>md ok200
新建多個目錄:>md ok300 ok400
刪除空目錄:>rd ok100
刪除目錄、子目錄和文件,不帶詢問:>rd /q/s ok200
刪除目錄、子目錄和文件,帶詢問:>rd /s ok200
文件的操作:
新建或追加內(nèi)容到文件:>d:\test100\abc100\abc .txt
??>echo atguigu > abc2 .txt
復(fù)制文件:>copy abc .txt ?d:\test200 使用原來文件名
??>copy abc .txt ?d:\test200\ok.txt 重寫指定名
移動文件:>move abc-txt ?f:\
刪除指定文件:>del abc2.txt
刪除所有文件:>del *.txt
?
變量:
①變量表示內(nèi)存中的一個存儲區(qū)域
②該區(qū)域有自己的名稱(變量名)和類型(數(shù)據(jù)類型)
?

Golang變量使用的三種方式
①Golang的變量如果沒有賦初值,編譯器會使用默認(rèn)值:
int默認(rèn)值0 ;string默認(rèn)值為空串;小數(shù)默認(rèn)為0。
②根據(jù)值自行判定變量類型(類型推導(dǎo)):var num = 10.11
③省略var,注意:=左側(cè)的變量不應(yīng)該是已經(jīng)聲明過的,否則會導(dǎo)致編譯錯誤:
name := “tom”?等價于var name string name = "tom"
④多變量聲明:
var n1,n2,n3 int
var n1,name, n3 =?100,"tom”,888
n1,name , n3?:=?18e,"tom",888
一次性聲明多個全局變量:
var (
n3 = 300
n4 =900
name2 = "mary"
)
⑤該區(qū)域的數(shù)據(jù)值可以在同一類型范圍內(nèi)不斷變化(重點)
⑥變量在同一個作用域(在一個函數(shù)或者在代碼塊)內(nèi)不能重名
⑦變量=變量名+值+數(shù)據(jù)類型,變量的三要素

數(shù)據(jù)類型:



整數(shù)型:
①分類:有符號int、無符號uint,大小和系統(tǒng)有關(guān)。
②默認(rèn)為int型。
③如何在程序查看某個變量的字節(jié)大小和數(shù)據(jù)類型(使用較多):
var n2 int64 =10
fmt.Printf("n2的類型%T??n2占用的字節(jié)數(shù)是%d ", n2, unsafe.Sizeof(n2))
④遵守保小不保大的原則。
⑤bit:計算機(jī)中的最小存儲單位。Byte:計算機(jī)中基本存儲單元。1byte = 8 bit
?

小數(shù)、浮點型:
①浮點數(shù)=符號位+指數(shù)位+尾數(shù)位,浮點數(shù)都是有符號的。
②尾數(shù)部分可能丟失,造成精度損失。
③默認(rèn)為float64類型。
④表示形式:
十進(jìn)制數(shù)形式:5.12??.512(必須有小數(shù)點)
科學(xué)計數(shù)法形式:5.1234e2?=?5.12*10的2次方
5.12E-2?=?5.12/10的2次方
?
字符型:
Golang中沒有專門的字符類型,如果要存儲單個字符(字母),一般使用 byte來保存。
字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個字節(jié)連接起來的。也就是說對于傳統(tǒng)的字符串是由字符組成的,而Go的字符串是由字節(jié)組成的。
①字符常量是用單引號(")括起來的單個字符。
②Go中允許使用轉(zhuǎn)義字符\’來將其后的字符轉(zhuǎn)變?yōu)樘厥庾址统A俊?/p>
③Go 語言的字符使用UTF-8編碼。英文字母:1個字節(jié);漢字:3個字節(jié)
④在Go中,字符的本質(zhì)是一個整數(shù),直接輸出時,是該字符對應(yīng)的UTF-8編碼的碼值。
⑤可以直接給某個變量賦一個數(shù)字,然后按格式化輸出時%c,會輸出該數(shù)字對應(yīng)的unicode字符:
var c4 int = 22269 ????// 22269 ->‘國’120->‘x’
fmt.Printf("c4=%c\n",c4)
⑥字符類型是可以進(jìn)行運算的,相當(dāng)于一個整數(shù),因為它都對應(yīng)有Unicode碼。
?
字符型存儲到計算機(jī)中,需要將字符對應(yīng)的碼值(整數(shù))找出來:
存儲:字符--->對應(yīng)碼值--->二進(jìn)制--->存儲
讀取:二進(jìn)制--->碼值--->字符--->讀取
?
布爾類型(bool類型):
①只允許取值true和false。
②占1個字節(jié)。
③適于邏輯運算,一般用于程序流程控制。
④默認(rèn)為false
?
String類型:
Go的字符串是由單個字節(jié)連接起來的。
Go語言的字符串的字節(jié)使用UTF-8編碼標(biāo)識 Unicode文本。
字符串一旦賦值了,字符串就不能修改了:在Go中字符串是不可變的。
兩種表示形式:
雙引號:會識別轉(zhuǎn)義字符
反引號:以字符串的原生形式輸出,包括換行和特殊字符,可以實現(xiàn)防止攻擊、輸出源代碼等效果。
?
基本數(shù)據(jù)類型的相互轉(zhuǎn)換:
Go在不同類型的變量之間賦值時需要顯式轉(zhuǎn)換。也就是說Golang中數(shù)據(jù)類型不能自動轉(zhuǎn)換。
①可從表示范圍小-->表示范圍大,也可從范圍大--->范圍小
②被轉(zhuǎn)換的是變量存儲的數(shù)據(jù)(即值),變量本身的數(shù)據(jù)類型并沒有變化!
var i int32 = 100
var n int64 = int64(i)
i還是int32
③int64轉(zhuǎn)成int8【-128--127】,編譯時不會報錯,轉(zhuǎn)換的結(jié)果是按溢出處理。
?
練習(xí):
var n1 int32 =12
var n2 int64
var n3 int8
var n4?int8
n2 =n1+20 //int32 ---> int64錯誤
n3 =n1+20 //int32--->int8錯誤
n2 = int64(n1)+ 20 //正確
n3 = int8(n1) +20 //正確
n4 = int8(n1)+127 //編譯通過,但是結(jié)果不是127+12,按溢出處理
n3 = int8(n1)+128 //編譯不過,編譯器認(rèn)為int8最大128,怎么還能加128呢?
?
基本數(shù)據(jù)類型和string的轉(zhuǎn)換
基本數(shù)據(jù)類型 → string:
①fmt.Sprintf("%參數(shù)",表達(dá)式) ??[常用、靈活]
func?Sprintf(format string,a ...interface{})string
Sprintf根據(jù)format參數(shù)生成格式化的字符串并返回該字符串。
var numi int =99
var num2 float64 =23.456
var b bool =true
var mychar byte = 'h'
var str string ?//空的str
str = fmt.Sprintf("%d" , num1)
str = fmt.Sprintf("%f"", num2)
str = fmt.Sprintf("t", b)
str = fmt.Sprintf(%c", mychar)
?
②使用strconv包的函數(shù):
?

var num3 int = 99
var num4 f1oat64 = 23.456
var b2 bool = true
str = strconv.FormatInt(int64(num3),10)
// strconv.FormatFloat(num4,'f',10,64)
//’f’:格式;10:小數(shù)位保留10位;64:這個小數(shù)是float64
str = strconv.FormatFloat(num4,"f',10,64)
str = strconv.FormatBoo1(b2)
?
var num5 int64 =4567
str = strconv. Itoa(int(num5))
string → 基本數(shù)據(jù)類型:
①使用strconv包的函數(shù):
?

var str string = “true"
var b bool
// strconv.ParseBool(str)函數(shù)會返回兩個值(value bool, err error)
//因為我只想獲取到value bool,不想獲取err,所以使用_忽略
b , _= strconv.ParseBool(str)
?
var str2 string = “1234590”
var n1 int64
var n2 int
n1 , _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
?
var str3 string = "123.456"
var f1 float64
f1 , _= strconv.ParseFloat(str3,64)
指針:
①獲取地址&
②指針變量存的是一個地址,這個地址指向的空間存的才是值:var ptr *int = &num
引用:
①值類型:變量直接存儲值,內(nèi)存通常在棧中分配
②引用類型:變量存儲的是一個地址,這個地址對應(yīng)的空間才真正存儲數(shù)據(jù)(值),內(nèi)存通常在堆上分配,當(dāng)沒有任何變量引用這個地址時,該地址對應(yīng)的數(shù)據(jù)空間就成為一個垃圾,由GC來回收。
?
標(biāo)識符:
①由26個英文字母大小寫,0-9 ,_組成
②數(shù)字不可以開頭。
③嚴(yán)格區(qū)分大小寫。說明:在golang 中,num和 Num是兩個不同的變量
④標(biāo)識符不能包含空格。
⑤下劃線"_"在Go中稱為空標(biāo)識符??梢?strong>代表任何其它的標(biāo)識符,但是它對應(yīng)的值會被忽略(比如:忽略某個返回值)。所以僅能被作為占位符使用,不能作為標(biāo)識符使用。
⑥不能以系統(tǒng)保留關(guān)鍵字作為標(biāo)識符(一共有25個),比如 break,if等等..
?
①包名:保持package 的名字和目錄保持一致,簡短,有意義,不要和標(biāo)準(zhǔn)庫不要沖突。
②變量名、函數(shù)名、常量名:采用駝峰法:xxxYyyyyZzzz...
③如果變量名、函數(shù)名、常量名首字母大寫,則可以被其他的包訪問;
如果首字母小寫,則只能在本包中使用(首字母大寫是公開的,首字母小寫是私有的),在golang沒有public,private 等關(guān)鍵字。

?

運算符:
①算術(shù)運算符
?

Golang的++和--只能寫在變量的后面:沒有++i、--i
Golang 的自增自減只能當(dāng)做一個獨立語言使用,不能這樣使用:if i++>0;i=i++
②賦值運算符

?

③比較運算符/關(guān)系運算符

④邏輯運算符
?

⑤位運算符
?

⑥其它運算符
?

優(yōu)先級:

?
Go語言明確不支持三元運算符。
?
鍵盤輸入:
①導(dǎo)入fmt包
②調(diào)用fmt包的fmt.Scanln()或者fmt.Scanf():
fmt.Scanf("%s %d %f %t",&name, &age,&sa1, &isPass)
?
進(jìn)制:
①二進(jìn)制。在golang中,不能直接使用二進(jìn)制來表示一個整數(shù),它沿用了c的特點。
②十進(jìn)制。
③八進(jìn)制。以數(shù)字0開頭表示。
④十六進(jìn)制:0-9,A-F。以O(shè)x或OX開頭表示?!続-F不區(qū)分大小寫】
?

轉(zhuǎn)十進(jìn)制:

?

?

二→八:每三位轉(zhuǎn)
二→十六:每四位轉(zhuǎn)
八→二:一位數(shù)轉(zhuǎn)三位
十六→二:一位數(shù)轉(zhuǎn)四位
?
原碼、反碼、補碼:
①二進(jìn)制的最高位是符號位:0表示正數(shù),1表示負(fù)數(shù):1 ===>[0000 0001];?-1===>[1000 0001]
②正數(shù)的原碼,反碼,補碼都一樣
③負(fù)數(shù)的反碼?=?它的原碼符號位不變,其它位取反(0->1,1->0)
④負(fù)數(shù)的補碼?=?它的反碼+1
⑤0的反碼,補碼都是0
⑥在計算機(jī)運算的時候,都是以補碼的方式來運算的:1-1=1+(-1)
?
按位與&;按位或|;按位異或^
計算 -2^2:
-2的原碼1000 0010?→ 反碼1111 1101?→ 補碼1111 1110
2的補碼?0000 0010
得11111100?(補碼) →原碼
補碼1111 1100?→ 反碼1111 1011?→ 原碼1000 0100 ==?-?4
?
右移運算符>>:低位溢出,符號位不變,并用符號位補溢出的高位
左移運算符<<:符號位不變,低位補0
?
If條件表達(dá)式:嵌套分支不宜過多,建議控制在3層內(nèi)。
Switch分支控制:匹配項后面也不需要再加break。
①default語句不是必須的.
②switch后也可以不帶表達(dá)式,類似if --else分支來使用。
③switch 后也可以直接聲明/定義一個變量,分號結(jié)束,不推薦。
switch grade := 90; {
case grade > 90 :…
④switch穿透:如果在case語句塊后增加fallthrough,則會繼續(xù)執(zhí)行下一個case。
⑤switch語句還可以被用于type-switch來判斷某個interface變量中實際指向的變量類型。
var x interface{}
var y =10.0
x = y
switch i :=x.(type){
case nil:
fmt.Printf("x的類型~:%T", i )
for循環(huán):
A.?for i := 1; i<10; i++ {…}
B.?j:=1 ?for j<10{…}
C.?j:=1 ?for { if j<10{…}…}
D.?for {…}。等價for ; ;是一個無限循環(huán),通常需要配合break語句使用
Golang提供for-range的方式,可以方便遍歷字符串和數(shù)組。
傳統(tǒng)的字符串遍歷:
var str string ="hello,wor1d!"
for i:=0; i< len(str); i++{
fmt.Printf("%c \n",str[i])
} //使用到下標(biāo)...
for-range:
str = "abc~ok"
for?index, val := range?str {
fmt.Printf("index=%d,val=%c \n", index,val)
}
如果字符串含有中文,則傳統(tǒng)的遍歷字符串方式,就是錯誤,會出現(xiàn)亂碼。原因是傳統(tǒng)的對字符串的遍歷是按照字節(jié)來遍歷,而一個漢字在utf8編碼是對應(yīng)3個字節(jié)。
?
解決辦法:
①需要要將str轉(zhuǎn)成rune切片
var str string ="hello,wor1d!北京"
str2 := []rune(str)
for i :=0;?i<len(str2); i++?{
fmt.Printf("%c?\n", str2[i]) //使用到下標(biāo)...
}
②for-range是按照字符方式遍歷。字符串有中文,也是ok。
str = "abc~ok上?!?/p>
for index,val :=range str {
fmt.Printf("index=%d,val=%c \n", index, val)
}
Go語言沒有while和 do...while語法
多重循環(huán)控制(重點,難點)
①嵌套循環(huán):在外邊的 for稱為外層循環(huán)在里面的 for循環(huán)稱為內(nèi)層循環(huán)。【建議一般使用兩層,最多不要超過3層】
②只有內(nèi)層循環(huán)的循環(huán)條件為false時,才會完全跳出內(nèi)層循環(huán),才可結(jié)束外層的當(dāng)次循環(huán),開始下一次的循環(huán)。
③外層循環(huán)次數(shù)為m次,內(nèi)層為n次,則內(nèi)層循環(huán)體實際上需要執(zhí)行m*n次。
?
隨機(jī)生成1-100整數(shù):
//time.Now().Unix():返回一個從 1970 1-1 0:0:0 到現(xiàn)在的一個秒數(shù)rand.Seed(time.Now().Unix())
fmt.Println("n", rand.Intn(100)+1)
?
跳轉(zhuǎn)控制語句:break、continue、goto、return
continue:
①用于結(jié)束本次循環(huán),繼續(xù)執(zhí)行下一次循環(huán)。
②出現(xiàn)在多層嵌套的循環(huán)語句體中時,可以通過標(biāo)簽指明要跳過的是哪一層循環(huán)。
goto:
①可以無條件地轉(zhuǎn)移到程序中指定的行。
②通常與條件語句配合使用??捎脕韺崿F(xiàn)條件轉(zhuǎn)移,跳出循環(huán)體等功能。
③在Go程序設(shè)計中一般不主張使用goto語句,以免造成程序流程的混亂。
var n int = 30
fmt.Print1n("ok1")
if n> 20?{
goto label1
}
fmt.Print1n("ok2")
label1:
fmt.Println("ok5")
?
包:
go的每一個文件都是屬于一個包的,go是以包的形式來管理文件和項目目錄結(jié)構(gòu)的。
作用:
區(qū)分相同名字的函數(shù)、變量等標(biāo)識符
當(dāng)程序文件很多時,可以很好的管理項目
控制函數(shù)、變量等訪問范圍,即作用域
相關(guān)說明:
打包:package包名
引入:import "包的路徑"
?import (
"包名"
"包名"
)
被調(diào)用的類的類名首字母要大寫,相當(dāng)于public
調(diào)用函數(shù):包名.函數(shù)名( )
如果包名較長,Go支持給包取別名:取別名后,原來的包名就不能使用了
import(
util?"go_code/chaptere6/fundemoo1/utils"
)
import包時,路徑從$GOPATH的src下開始,不用帶src,編譯器會自動從src下開始引入。
文件的包名通常和文件所在的文件夾名一致,一般為小寫字母。
?
?