




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第2章Go語言基礎標
識
符01標識符及命名規范標識符及命名規范Go語言的標識符命名規范如下。(1)標識符由任意多個字符(大/小寫字母A~Z/a~z)、數字(0~9)、下畫線(_)組成。(2)第一個字符必須是字母或下畫線。(3)區分大小寫,如hello與Hello是兩個不同的標識符。(4)標識符中不能含有空格及#、$、@等特殊符號。例如:_123 //合法123 //非法,不能以數字開頭a123 //合法$a123 //非法,不能以特殊符號開頭HelloWorld //合法HelloWorld //非法,不能含有空格Subject //合法Subject# //非法,不能含有#02關
鍵
字關鍵字Go是一門極簡的語言,僅有25個關鍵字,它們按功能的不同大致可分為3類,見下表所示。分
類關鍵字功
能引導程序整體結構package聲明程序所在的包import導入程序要用的外部(含第三方)包var聲明變量const聲明常量func聲明和定義函數defer延遲執行go并發執行return函數返回值定義特殊類型type自定義類型struct定義結構interface定義接口map聲明或創建映射chan創建通道(并發編程)控制程序流程if條件語句elsefor控制循環rangebreakcontinueswitch分支語句selectcasedefaultfallthroughgoto跳轉語句03保
留
字保留字除關鍵字外,Go語言還有一些內部保留字,用于預定義內置的數據類型、函數及常量。Go共有39個保留字,分類列于表。分類保留字說
明內置數據類型int整型int8int16int32int64byte無符號整型uintuint8uint16uint32uint64uintptrfloat32浮點型float64complex64復數型complex128string字符串型runebool布爾型分類保留字說
明
error接口型內置函數make這些函數都是Go語言內置的,具有“全局可見性”,在編寫程序時可直接調用,無須import導入或聲明newlencapappendcopydeletepanicrecoverclosecomplexrealimagprintprintln內部常量true布爾型值falseiota連續的枚舉值nil指針/引用的默認空值第2章Go語言基礎變量與常量01變
量1.變量聲明2.變量賦值變
量1.變量聲明在Go語言中,變量的聲明比較靈活,有3種方式。(1)標準方式標準方式就是以關鍵字var顯式地聲明單獨的一個變量,格式為:var變量名類型例如:varnamestring //聲明字符串型變量namevarsexbool //聲明布爾型變量sexvarageint //聲明整型變量age(2)批量方式在需要使用一組相關的多個變量的情形下,用批量方式進行聲明會更加高效。此方式根據多變量類型是否相同,又有兩種不同的聲明形式,如下。①類型相同多變量的聲明當要聲明的幾個變量類型都相同時,只須在標準方式的基礎上擴充即可,格式變為:var變量名1,變量名2,...,變量名n類型例如:varage,weight,heightint //聲明3個整型變量age、weight、height變
量②類型不同多變量的聲明當要批量聲明的一組相關變量的類型不同時,Go語言提供一種新方法,用關鍵字var搭配括號將這組變量的定義放在一起,格式為:var(
變量名1類型1
變量名2類型2 ...
變量名n類型n)例如:var( namestring //姓名 sexbool //性別 weightint //體重 heightint //身高 bmifloat32 //身體質量指數(體重÷身高2))變
量(3)簡短方式這種方式不用var關鍵字,直接以“:=”操作符在聲明變量的同時就對其進行初始化,格式為:變量名:=表達式 //聲明(同時初始化)單個變量或者變量名1,變量名2,...,變量名n:=表達式1,表達式2,...,表達式n //聲明多個變量(右邊表達式要與左邊變量名一一對應)變
量2.變量賦值(1)變量初始值凡用var關鍵字聲明的變量,Go系統都會自動賦予其初始值,為變量類型的零值或空值,比如,string類型為空字符串,bool類型為false,int類型為0等。【實例2.1】聲明并查看不同類型變量的初始值。程序代碼如下(var00.go):packagemainimport"fmt"funcmain(){ varnamestring //標準方式聲明字符串變量 varweight,heightint //批量方式聲明同類型變量 var( sexbool ageint bmifloat32 ) //批量方式聲明不同類型變量 note:="我的體態" //簡短方式聲明并初始化變量 //輸出各變量的初始值 fmt.Println(note+"\n姓名:"+name) fmt.Println("性別:",sex) fmt.Println("年齡:",age) fmt.Println("體重:",weight) fmt.Println("身高:",height) fmt.Println("BMI指數:",bmi)}運行結果如圖。變
量(2)單變量賦值給單個變量賦值的語句標準格式為:var變量名[類型]=值其中,“類型”可省略,Go編譯器能夠根據所賦值的數據類型自動推斷出變量的類型,例如,下面這兩條語句是等價的:varnamestring="周何駿" //單變量賦值varname="周何駿" //單變量賦值(省略類型)變
量(3)多變量賦值給多個變量賦值的程序代碼的標準格式為:var(
變量名1[類型1]=值1
變量名2[類型2]=值2 ...
變量名n[類型n]=值n)這里各個變量的類型也是可以省略的,交給Go編譯器自行推斷。例如:var( namestring="周何駿" //姓名 sexbool=true //性別 weightint=60 //體重 heightint=173 //身高 bmifloat32=20.05 //身體質量指數(體重÷身高2))變
量也可以將多個變量的賦值語句寫為一行,形如:var變量名1,變量名2,...,變量名n=值1,值2,...,值n各變量名與所賦的值按順序對應列于等號的兩邊,中間以英文逗號(,)分隔,要注意變量與值的一一對應關系。變量類型可以相同也可以不同,編譯器能自動識別。例如:varweight,height=60,173 //類型相同的多變量賦值varname,sex,age="周何駿",true,19 //類型不同的多變量賦值變
量【實例2.2】用多種不同方式給單個或多個變量賦值,并查看所賦的值。程序代碼如下(var01.go):packagemainimport"fmt"funcmain(){ varname="周何駿" //單變量賦值 varweight,height=60,173 //多變量賦值(寫為一行) var( sex=true age=19 bmi=20.05 ) //多變量賦值(標準格式) note:="我的體態" //輸出各變量所賦的值 fmt.Println(note+"\n姓名:"+name) fmt.Println("性別:",sex) fmt.Println("年齡:",age) fmt.Println("體重:",weight) fmt.Println("身高:",height) fmt.Println("BMI指數:",bmi)}運行結果如圖。02常
量1.常量聲明2.常量初始化常
量1.常量聲明Go語言的常量使用關鍵字const聲明,格式如下:const常量名[類型]=值常量必須在聲明的同時就賦一個確定值,這是與變量不一樣的地方。大家會發現,常量聲明語句與單變量的賦值語句在形式上一樣,其“類型”也可省略,由編譯器來推導。例如:constefloat32=2.71828 //自然常數econstcint=299792458 //光速cconstg=6.67e-11 //引力常數G(省略類型)constpi=3.1416 //圓周率π(省略類型)constlanguagestring="Go語言" //字符串常量constsexbool=true //布爾型常量常
量也可以像變量聲明那樣批量聲明一組常量,只須用關鍵字const搭配括號,如下:const( name="周何駿" sex=true weight=60 height=173)常量的值必須是能夠在編譯時就被確定的,可以在其賦值表達式中涉及計算過程,但是所有用于計算的值必須在編譯期間就能獲得,例如://錯誤(weight、height為變量,直到運行期才被賦值)varweight,height=60,173constbmi=weight/((height/100)^2)
//正確(weight、height為常量,在編譯期就能得到值)constweight,height=60,173constbmi=weight/((height/100)^2)常
量2.常量初始化對于一組數值間存在遞增(減)關系的常量,可以使用Go語言的常量生成器iota進行初始化。iota可自動生成一組以相似規則初始化的常量,而不用每行都寫一遍初始化表達式。在一個const聲明語句中,第1個聲明的常量所在行的iota會被置為0,之后的每一個有常量聲明的行iota會被自動加1,如下:const( c0=iota //c0==0 c1=iota //c1==1 c2=iota //c2==2 ... cn=iota //cn==n)也可以簡寫為:const( c0=iota //c0==0 c1 //c1==1 c2 //c2==2 ... cn //cn==n)常
量【實例2.3】用生成器iota初始化月份常量值。程序代碼如下(const.go):packagemainimport"fmt"funcmain(){ const( month=iota Jan Feb Mar Apr ) fmt.Print(Jan,"月、",Feb,"月、",Mar,"月、",Apr,"月...")}運行結果如圖。第2章Go語言基礎運算符與表達式運算符與表達式1.運算符Go語言有幾十種運算符,被分為了十幾個類別,詳見下表。優先級分
類運
算
符結合性1(最高)括號()、[]從左向右2單目運算符!、*(指針)、&、++、--、+(正號)、-(負號)從右向左3乘/除/取余*、/、%從左向右4加/減+、-從左向右5位移運算符<<、>>從左向右6關系運算符<、<=、>、>=從左向右7等于/不等于==、!=從左向右8按位“與”&從左向右9按位“異或”^從左向右10按位“或”|從左向右11邏輯“與”&&從左向右12邏輯“或”||從左向右13賦值運算符=、+=、-=、*=、/=、%=、>=、<<=、&=、^=、|=從右向左14逗號運算符,從左向右運算符與表達式2.優先級和結合性(1)算術運算符優先級同數學因Go語言中大部分算術運算符(包括加/減/乘/除/取余等)的優先級和數學中是一致的,故只要知道數學運算的優先級即可正確計算算術表達式的值,例如:vara,b,cint=2,4,8d:=a+b*c對于第2行程序語句中的表達式“a+b*c”,按照數學運算規則,應該先計算乘法,再計算加法。(2)加括號的部分最先算從上表可見,第1行括號的優先級為最高,故不管表達式如何復雜,都要首先計算其加括號的部分。例如,要想改變表達式“a+b*c”的求值順序,先計算加法后計算乘法,只須對其加法部分加括號,語句改為如下:d:=(a+b)*c運算符與表達式(3)多個括號最內層最優先當表達式中有多個括號嵌套時,最內層的括號最優先。例如:constbmi=weight/((height/100)^2)計算時應當先執行內層括號里的“height/100”(將身高換算成米為單位),然后才執行外層括號的乘方(^2)運算。(4)其余遵循Go語言運算符優先級對于由多種不同類別運算符混合構成的表達式,則根據Go語言運算符的優先級來決定運算順序,可參照上表。運算符的結合性是指,當相同優先級的運算符在同一個表達式中(且沒有括號)時,計算的順序,通常有“從左向右”和“從右向左”兩個方向。運算符與表達式3.運算符測試(1)自增(++)和自減(--)運算符自增(如a++,a是變量)表示將變量值加1。Go語言為了保持簡潔性,避免混淆和錯誤,取消了對前綴自增(如++a)的支持,這與絕大多數語言如C/C++、Java等都不一樣。同理,自減也僅支持后綴自減(如a--),表示將變量值減1。另外,GO中的a++、a--等都是語句而非表達式,必須單獨寫為一行。【實例2.4】測試自增和自減運算符。程序代碼如下(opt01.go):運行結果如圖。運算符與表達式(2)位運算符位運算符是對變量值按其在計算機內部的二進制表示按位進行操作的一類運算符,介紹如下。①按位“與”(&)對參與運算的兩個數值相應的二進制位進行與運算,規則為:0&0=0,0&1=0,1&0=0,1&1=1。②按位“或”(|)對參與運算的兩個數值相應的二進制位進行或運算,規則為:0|0=0,0|1=1,1|0=1,1|1=1。③按位“異或”(^)對參與運算的兩個數值相應的二進制位進行異或運算,即相同的是0、不相同是1:0^0=0,1^0=1,0^1=1,1^1=0。異或運算還有一個特別的性質,對于兩個整數x、y,表達式(x^y)^y的值又會還原為x,利用這個特性可以對數值進行加密。④右移(>>)將一個數值的所有二進制位向右移若干位,右移后左邊空出的位用0填充。向右移一位相當于整除2(舍棄小數部分)。⑤左移(<<)將一個數值的所有二進制位向左移若干位,右邊空出的位填0。左邊移出的位并不丟棄(依然有效),故左移一位相當于乘以2。運算符與表達式【實例2.5】測試位運算符。程序代碼如下(opt02.go):運行結果如圖。第2章Go語言基礎基本數據類型01整
型整
型Go語言內置了多達12種整型,大體分為無符號與有符號兩大類,各整型的名稱、描述及取值范圍如表。分類名稱描
述取值范圍無符號uint88位整型0~255byteuint8的別名0~255uint1616位整型0~65535uint3232位整型0~4294967295uint6464位整型0~18446744073709551615uint32或64位(基于架構)的整型—uintptr用于存放指針的整型(基于架構)—有符號int88位整型-128~127int1616位整型-32768~32767int3232位整型-2147483648~2147483647int6464位整型-9223372036854775808~9223372036854775807int32或64位(基于架構)的整型—整
型其中,uint、uintptr和int這3個類型是基于架構的,即它們的位數由實際運行程序的操作系統來決定,在32位操作系統上就是32位(4個字節)的整型,而在64位操作系統上則變成64位。不同類型的整型變量在相互賦值時必須進行強制類型轉換,例如:varaint=2varbint32b=int32(a) //正確//b=a //錯誤fmt.Println("b=",b)整
型整型常量有十進制、八進制、十六進制三種表示法,十進制直接寫出數值,八進制值以數字0開頭,十六進制則以0x或0X開頭,例如:variint=123 //十進制正整數fmt.Println("i=",i) //i=123
variint=-48 //十進制負整數fmt.Println("i=",i) //i=-48
variint=017 //八進制正整數fmt.Println("i=",i) //i=15
variint=-021 //八進制負整數fmt.Println("i=",i) //i=-17
variint16=32768fmt.Println("i=",i) //錯誤,超范圍
variint=0x12a6 //十六進制數fmt.Println("i=",i) //i=4774(1*16^3+2*16^2+10*16+6)
vara,b=0xAB12,-0x1a0 //十六進制數fmt.Print("a=",a,",b=",b) //a=43794,b=-41602浮點型浮點型浮點型用于表示包含小數點的數值,Go語言內置兩種浮點型:float32和float64,分別表示32位和64位的浮點數,它們都遵循IEEE754標準,該標準采用二進制數據的科學記數法來表示浮點數,如下。float32:用1位表示數字的符號,用8位表示指數(底數為2),用23位表示尾數,最大范圍為3.40282346638528859811704183484516925440e+38。float64:用1位表示數字的符號,用11位表示指數(底數為2),用52位表示尾數,最大范圍為1.797693134862315708145274237317043567981e+308。浮點型浮點型數有兩種表示形式,如下。(1)十進制小數形式直接寫出含小數點的數,當數的整數或小數部分為0時可省略小數點前或后的數字,但小數點兩邊的數字不能同時省略且小數點不能省略,例如:varffloat32=3.14fmt.Println("f=",f) //f=3.14
varffloat32=5.fmt.Println("f=",f) //f=5
varffloat32=.618fmt.Println("f=",f) //f=0.618
varffloat32=036.70fmt.Println("f=",f) //f=36.7
varffloat32=. //錯誤,小數點兩邊的數字不能同時省略fmt.Println("f=",f)浮點型(2)科學記數法形式如1.26×10-21表示為1.26e-21或1.26E-21,e或E的前面必須有數字且后面必須是一個正/負整數(正號可省略),例如:consthfloat64=6.62607015E-34 //普朗克常數fmt.Println("h=",h) //h=6.62607015e-34
constcfloat32=2.99792458e8 //真空中的光速fmt.Println("c=",c) //c=2.9979245e+08
constcfloat64=2.99792458e8fmt.Println("c=",c) //c=2.99792458e+08
constcfloat64=.299792458E09fmt.Println("c=",c) //c=2.99792458e+08
varffloat32=4.e+0fmt.Println("f=",f) //f=4
varffloat32=6E3fmt.Println("f=",f) //f=6000浮點型使用浮點型還要特別注意兩點:(1)浮點型變量會被Go編譯器默認推斷為float64型。(2)目前的計算機事實上并不能精確表示和存儲浮點數,因此不應當在程序中使用==或!=直接比較兩個浮點數。例如:f1:=2.71828varf2float32=f1 //錯誤,f1為float64型varf2float32=float32(f1) //正確
constpi=math.Pi //圓周率πvarpfloat64=3.1415926 //祖沖之計算值fmt.Println(p==pi) //false,直接比較一定是不相等的fmt.Println(math.Abs(p-pi)<1e-6) //true,應當采用差的絕對值小于給定誤差來判斷03復數型復數型Go語言原生支持復數,內置了兩種復數型:complex64和complex128。復數在計算機內部用兩個浮點型數表示,一個為實部另一個為虛部。相應地,Go的復數型也由兩個浮點型構成,complex64是由兩個float32浮點型構成的,而complex128則是由兩個float64浮點型構成的。在程序中,復數型數的寫法與數學表示法一樣,其實部和虛部數值的表示形式同浮點型,例如。此外,Go還有3個內置函數專用于處理復數,使用如下:varc=complex(2.718,0.618) //構造一個復數a:=real(c) //返回實部b:=imag(c) //返回虛部fmt.Print("c=(",a,"+",b,"i)") //c=(2.718+0.618i)04布爾型1.布爾運算2.布爾型的轉換布爾型1.布爾運算布爾型無法參與數值運算,故不可用算術運算符(+、-、*、/、%等)對它進行操作,但可以用邏輯運算符(&&、||、!)將多個關系表達式、布爾型變量(或常量)組成一個邏輯表達式(布爾表達式)進行運算,稱為“布爾運算”,規則為:(1)a&&b(“與”運算):只有a與b都為true,結果才為true;有一個為false,結果就為false。(2)a||b(“或”運算):只有a與b都為false,結果才為false;有一個為true,結果就為true。(3)!a(“非”運算):單目運算符!取與a值相反的布爾值,因此!true的值為false。布爾型布爾運算的結果一定也是布爾型值,另外,關系運算符(<、<=、>、>=、==、!=等)的比較操作也會產生布爾型的值。例如:fmt.Println(!true==false) //true
varb=88fmt.Println(b==86) //false
varx,y=14,8fmt.Println((x-y)<2*4) //truefmt.Println((x>y)&&((x-y)>7)) //false布爾型2.布爾型的轉換在Go語言中,布爾型無法與其他數據類型直接轉換,例如,不允許將布爾型強制轉換為整型來參與算術運算:varb=truefmt.Println(int(b)+2)編譯錯誤,輸出信息:cannotconvertb(variableoftypebool)totypeint而且,布爾值也不會隱式轉換為數值0或1,反之亦然,只能編寫程序代碼進行轉換:varb=truefmt.Println(b+2) //錯誤varbVal=0ifb{ bVal=1}fmt.Println(bVal+2) //正確,輸出3布爾型【實例2.6】布爾運算判斷性別。程序代碼如下(bool.go):packagemainimport( "fmt" "strings" //Go語言內置字符串處理包)funcmain(){ var( namestring="王燕" //姓名 profession="女博士" //身份 sexbool=true //性別(男:true;女:false) ) vargenderbool=strings.Contains(profession,"女")||!sex varsexString="男性" ifgender{ sex=false sexString="女性" } fmt.Println("sex=",sex) fmt.Print(name+"是一名",sexString)}運行結果如圖。05字符串型1.字符串創建2.字符串訪問3.字符串修改字符串型1.字符串創建Go語言將字符串作為一種原生的基本數據類型,創建一個字符串非常容易,如:vars="Hello,Go語言!"這句代碼聲明了字符串s,并初始化其內容為“Hello,Go語言!”。【實例2.7】字符串內容的兩種引用方式。程序代碼如下(string01.go):packagemainimport"fmt"funcmain(){ s1:="我愛\"Go語言\"編程\n@easybooks" //支持轉義,但不能跨行 s2:=`我愛\"Go語言\"程序設計\n@easybooks` //可以跨行,但不支持轉義 fmt.Println(s1) fmt.Println(s2)}運行結果如圖。字符串型實際應用中,雙引號使用最廣泛,而反引號多用在書寫多行消息文本、HTML源碼及正則表達式的場合。Go語言的字符串是不可變的,但可以對其進行級聯(+)和追加(+=)操作,例如:s:="我愛"+"Go語言編程!"fmt.Println(s) //我愛Go語言編程!s+="@easybooks"fmt.Println(s) //我愛Go語言編程!@easybooks字符串型2.字符串訪問(1)單字節字符串訪問如果一個字符串全部由單字節字符構成,就是“單字節字符串”,如:s1:="IloveGoprogramming!"s2:="HelloWorld!"s3:="Hello,Golanguage.@easybooks"單字節字符串可以通過索引直接提取其任意位置的字節,在方括號[]內寫入索引,索引從0開始計數,如對于字符串s,s[0]訪問其首字節,s[i-1]訪問第i個字節,s[len(s)-1]則訪問最后1個字節,如果想要獲取字節所對應的字符內容,則通過string轉換,如第i個字節的字符為string(s[i-1])。字符串型【實例2.8】單字節字符串的訪問。程序代碼如下(string02.go):packagemainimport"fmt"funcmain(){ s:="Hello,Golanguage.@easybooks" fmt.Println("總字節數:",len(s)) fmt.Println(s[0]) //索引位置為0(首字節)的ASCII碼值 fmt.Println(string(s[0])) //索引位置為0(首字節)對應字符 fmt.Println(s[6:8]) //截取索引位置6~7(不包含最后8)的字符串 fmt.Println(s[18:]) //從索引位置18(對應字符@)一直截取至末尾 fmt.Println(s[:5]) //截取索引位置0~4(不包含最后5)的字符串}運行結果如圖。字符串型(2)多字節字符串訪問如果字符串的字符不全是單字節的(比如含有中文),就不能直接使用索引訪問,Go語言專門提供了一個rune類型用于這類字符串的操作。rune是Go內部整型int32的別名,占4個字節(UTF-8編碼最大字節),能表示不同字長的字符。使用時,先將待訪問的字符串轉換為rune型,然后就可以按單字節索引的方式獲取指定位置的內容。【實例2.9】多字節字符串的訪問。程序代碼如下(string03.go):packagemainimport( "fmt" "unicode/utf8")funcmain(){ s:="Hello,Go語言。@easybooks" fmt.Println("總字節數:",len(s))//一個中文字符占3個字節 fmt.Println("總字符數:",utf8.RuneCountInString(s)) sc:=[]rune(s) //將字符串轉為rune型 fmt.Println(sc[0]) //索引位置為0(首字節)的ASCII碼值 fmt.Println(string(sc[0])) //索引位置為0(首字節)對應字符 fmt.Println(string(sc[6:11])) //截取索引位置6~10,不包含最后11(對應中文。) fmt.Println(string(sc[12:])) //從索引位置12(對應字符@)一直截取至末尾 fmt.Println(string(sc[:5])) //截取索引位置0~4(不包含最后5)的字符串}運行結果如圖。字符串型3.字符串修改在Go語言中,不能直接修改字符串的內容,比如,下面這種試圖修改指定字符的方式是不被允許的:s:="Hello,Go語言。@easybooks"s[6]="g"編譯錯誤,輸出信息:cannotassigntos[6](valueoftypebyte)要想修改字符串的內容,必須先將字符串復制到一個可寫的變量中,然后再進行修改。對于單字節和多字節字符串來說,接收它們的變量類型是不同的。(1)單字節字符串修改單字節字符串復制到一個byte類型(Go字節類,uint8的別名)變量中,如下:字符串:="......"變量:=[]byte(字符串)變量[索引]='值' //注意值要用單引號(不能用雙引號)引起來(2)多字節字符串修改多字節字符串修改則是先通過復制到一個rune類型變量,如下:字符串:="......"變量:=[]rune(字符串)變量[索引]='值' //注意值要用單引號(不能用雙引號)引起來字符串型【實例2.10】兩種字符串的修改。程序代碼如下(string04.go):packagemainimport"fmt"funcmain(){ //單字節字符串修改 ss:="Hello,Golanguage.@easybooks" fmt.Println("單字節:",ss) bStr:=[]byte(ss) //轉為byte型,字符串被自動復制到變量bStr bStr[6]='g' ss=string(bStr) fmt.Println("修改后:",ss)
//多字節字符串修改 sc:="Hello,Go語言。@easybooks" fmt.Println("多字節:",sc) rStr:=[]rune(sc) //轉為rune型,字符串被自動復制到變量rStr rStr[9]='程' rStr[10]='序' sc=string(rStr) fmt.Println("修改后:",sc)}運行結果如圖。第2章Go語言基礎程序流程控制01條件語句條件語句條件語句又稱if語句,它使部分程序代碼塊只有在滿足特定條件時才會被執行,語法格式為:if<布爾表達式1>{ <語句塊1>}[elseif<布爾表達式2>{ <語句塊2>}...}elseif<布爾表達式n>{ <語句塊n>}else{ <語句塊n+1>}]說明:(1)該語句首先計算<布爾表達式1>的值,若是true,則執行<語句塊1>,當<語句塊1>執行完成,整個if語句也就結束了;當<布爾表達式1>的值是false時,再計算<布爾表達式2>,若是true,則執行第一個elseif部分的<語句塊2>,當<語句塊2>執行完成,整個if語句執行結束;……以此類推,若所有布爾表達式的值都是false時,就執行else部分的<語句塊n+1>,執行完成后結束整個if語句。(2)整個語句只有if部分是必須的,后面所有的elseif和最后的else部分都是可選的,視程序邏輯需要可構成單獨的一個if、if-elseif、if-else或者if-elseif-else等多種不同結構的if語句變體。(3)與其他語言不同,Go語言if語句中用于判斷條件的布爾表達式不需要用括號括起來。條件語句(4)按照Go的語法,包裹每個語句塊的前半個大括號“{”必須放在行尾,而不能另起一行。如下面這幾種寫法都是錯誤的:if<布爾表達式1>{ <語句塊1>}elseif<布爾表達式2>{ //錯誤 <語句塊2>}else{ <語句塊3>}
if<布爾表達式1>{ //錯誤 <語句塊1>}
if<布爾表達式1>{ <語句塊1>}else{ //錯誤 <語句塊2>}(5)Go語言沒有其他語言都有的條件運算符(形如“表達式1?表達式2:表達式3”),因為用if語句就能夠實現條件運算符的功能。條件語句【實例2.11】用條件語句判斷用戶輸入年份是否為閏年。程序代碼如下(if.go):運行演示如圖。02分支語句分支語句分支語句又稱switch語句,它會根據傳入的參數檢測并執行符合條件的分支,當程序有多個分支(兩個以上)時,用它比用多個嵌套的if語句更加簡明,其語法格式如下:switch[<表達式>]{case<表達式1>: [<語句1>] [fallthrough]case<表達式2>: [<語句2>] [fallthrough]...case<表達式n>:[<語句n>][default:<語句n+1>]}分支語句說明:(1)該語句首先計算<表達式>的值,然后判斷該值與<表達式1>的值是否相等,若相等,則執行<語句1>;否則,繼續判斷<表達式>的值與<表達式2>的值是否相等,若相等,則執行<語句2>;……以此類推,若沒有一個表達式的值與<表達式>的值相等,則執行default后面的<語句n+1>。(2)與其他語言不同,Go的switch語句中的每一個case都是獨立的代碼塊,程序僅僅執行滿足條件的那個case后面的語句,而不會像其他語言那樣一直執行到底,故不需要通過break關鍵字跳出。(3)switch后面的<表達式>可省去,改由各個case后面的表達式直接判斷執行條件,這種情況case后面的表達式就必須是布爾表達式,其效果等同于多重“if-elseif-else”結構的條件語句。(4)語句中的各條件表達式不限于數值常量,可以是任意支持相等比較運算的類型變量。(5)在一個case分支的語句中,可以通過fallthrough語句來強制執行下一個case分支的語句而不管其表達式條件是否滿足。分支語句【實例2.12】用分支語句選擇輸出雷鋒叔叔的名言。程序代碼如下(switch.go):運行演示如圖。03循環語句循環語句循環語句的作用是反復執行一段代碼,直到不滿足循環條件為止。Go語言遵循“少即是多”的設計哲學,只提供了for循環語句,語法格式如下:for初始化;循環條件;迭代部分{
循環體}說明:(1)初始化:該部分是一個表達式,可缺省不寫。用來設置循環的初始條件,比如設置循環控制變量的初始值。(2)循環條件:這是一個布爾表達式,表示循環繼續執行的條件,每一次循環體執行完后都要對該表達式求值,以決定是否繼續循環。若該部分缺省不寫,則表示條件永遠為真(成為死循環)。(3)迭代部分:它也是一個表達式,同樣可以缺省不寫,用來改變循環控制變量的值,從而改變循環條件表達式的布爾值。循環語句(4)循環體:這是循環操作的主體部分,為任意合法Go語句組成的代碼塊,可以是一條語句,也可以是多條。for語句的執行流程是:第1步:首先計算“初始化”表達式,該表達式的值僅在此計算一次,以后不再計算。第2步:計算“循環條件”布爾表達式,若值為false,則結束整個for循環語句,程序繼續執行緊跟在該for語句之后的語句;若值為true,則依次執行循環體中的語句。第3步:循環體執行一次后,計算“迭代部分”表達式,再轉第2步。例如:vari,total=1,0forprice:=10.58;i<=100;i++{ total+=i ifi==100{ fmt.Println("price=",price) //price=10.58 }}fmt.Println("i=",i) //i=101fmt.Println("total=",total) //total=5050循環語句Go語言沒有大多數語言的while和do-while循環,但僅用for語句也能實現與這兩種循環完全一樣的功能,如下。(1)while循環等價實現將for語句的初始化省略,原迭代部分移至循環體末尾,即可實現與while循環等價的功能,代碼形式為:for循環條件{
循環體
迭代部分}例如:vari,total=1,0fori<=100{ total+=i i++}fmt.Println("total=",total) //total=5050循環語句(2)do-while循環等價實現將for語句的初始化、循環條件、迭代部分全部省略,迭代部分移至循環體末尾,其后用一個if語句判斷對循環條件取反的布爾表達式值,若為true跳出循環,如此就能夠實現與do-while循環等價的功能,代碼形式為:for{
循環體
迭代部分 if!循環條件{ break }}例如:vari,total=1,0for{ total+=i i++ if!(i<=100){ break }}fmt.Println("total=",total) //total=5050循環語句【實例2.13】用循環語句設計一個計算階乘的程序。說明:階乘(!)是基斯頓·卡曼(ChristianKramp,1760~1826)于1808年發明的運算符號,一個自然數n的階乘寫作n!,是所有小于及等于該數的正整數的乘積,亦即n!=1×2×3×...×(n-1)×n,并且規定0!=1。程序代碼如下(for01.go):packagemainimport"fmt"funcmain(){ varnint //接收輸入自然數 fmt.Print("請輸入:") fmt.Scanln(&n) vars=1 ifn!=0{ fori:=1;i<=n;i++{ s=s*i } } fmt.Print(n,"!=",s)}運行演示如圖。循環語句【實例2.14】用循環語句設計一個程序,輸出所有的水仙花數。說明:所謂水仙花數,是指一個3位數,其各位數字的立方和等于該數自身,例如,153=13+53+33。程序代碼如下(for02.go):packagemainimport"fmt"funcmain(){ vari=0 //百位數 varj=0 //十位數 vark=0 //個位數 varn,p=0,0 fmt.Println("水仙花數有:") form:=100;m<1000;m++{ i=m/100 //得到百位數 n=m%100 j=n/10 //得到十位數 k=n%10 //得到個位數 p=i*i*i+j*j*j+k*k*k ifp==m{ fmt.Println(m) //打印水仙花數 } }}運行結果如圖。04跳轉語句1.goto語句2.break語句3.continue語句4.return語句跳轉語句跳轉語句用于改變程序流程的方向,簡單直接。Go語言的跳轉語句常與標簽一起配合使用,標簽標識一個語句,通常寫在需要程序跳轉到的目標位置,如下:標簽名:
語句iGo的跳轉語句包括goto、break、continue和return,下面分別舉例說明它們的應用。1.goto語句goto語句可無條件地跳轉到指定標簽,格式為:...goto標簽L...標簽L:
語句i跳轉語句【實例2.15】在范圍n以內尋找勾股數,只要求找一組,找到后用goto語句迅速返回并輸出結果。說明:勾股數(又名畢氏三元數)最早見于《周髀算經》,也就是可以構成一個直角三角形三邊的一組正整數。因為根據勾股定理,直角三角形兩條直角邊a、b的平方和等于斜邊c的平方,所以滿足a2+b2=c2的a、b、c就是一組勾股數。程序代碼如下(goto.go):運行結果如圖。上面代碼中,在定義標簽FoundLabel之前有一個return語句,這是為了避免程序在未找到勾股數(但已正常結束退出循環)而運行到此處時也執行標簽標識的語句,輸出錯誤結果,如圖。跳轉語句2.break語句break用于從分支語句、循環語句或被標簽標識的代碼塊中強制退出。用break從循環體退出時,默認只能跳出最近的內層循環,當需要跳出多重循環時,可以在要退出的那層循環的代碼塊上加標簽,然后在break語句后面添加這個標簽,格式如下:標簽L: for...{ //要跳出這層循環 for...{ ... //多重循環 if條件{
語句塊 break標簽L } ... } }跳轉語句【實例2.16】尋找范圍n以內的勾股數,找到后用break語句返回并輸出結果。說明:此例的功能同【實例2.15】,所不同的是跳轉標簽是加在最外層for循環代碼塊上而非最終輸出結果的語句上,改用break語句實現程序的跳轉。程序代碼如下(break.go):運行結果如圖。跳轉語句3.continue語句continue語句也用于跳出循環,但與break不同的是,它僅跳出循環體的本次迭代,立即進入下一輪循環,繼續執行循環體。【實例2.17】打印100~200之間能被3整除的數,每10個數一行。程序代碼如下(continue.go):packagemainimport"fmt"funcmain(){ vari=0 forn:=100;n<=200;n++{ ifn%3!=0{ continue //若不能被3整除,跳出本次循環進入下一輪 } i++ fmt.Print(n,"") ifi%10==0{ //每10個數一行 fmt.Print("\n") } }}運行結果如圖。跳轉語句4.return語句return語句用于退出函數和方法,由此引發程序控制流程的跳轉。先前的實例已經使用return語句跳過標簽處的語句以避免輸出錯誤結果。return語句用在入口函數main中就是直接退出程序,而當用在其他函數或方法中時,如果函數或方法有返回值(列表),則return后面需要提供相應類型的返回值。第2章Go語言基礎復合數據類型01指
針1.指針的概念和性質2.指針修改與交換指
針1.指針的概念和性質假設變量a的類型為T(這里的T可以是int、float32、complex64、bool、string等任何具體的數據類型),在編程時,用“*”運算符聲明指針類型,*T就是該變量的指針;用“&”運算符獲取變量的內存地址,&a就是變量a的地址。指針作為一種特殊的變量類型,其變量名也就是指針名,變量值則是其中存放的地址值,也叫指針值。定義一個指針類型(*T型)的變量p,用“*”運算符可以取出指針所指的變量的值,*p就是變量a的值。可見,&取得的地址可以直接賦值給指針:var指針名*T=&變量名 //用地址給指針賦值反之,*提取的值又可以賦值給新的變量:var變量名T=*指針名 //用指針給變量賦值變量取地址的“&”與指針取值的“*”是一對互逆的運算符。指
針【實例2.18】測試指針的性質。程序代碼如下(pointer.go):packagemainimport"fmt"funcmain(){ variint=100 varpi*int=&i //用地址給指針賦值 varjint=*pi //用指針給變量賦值 fmt.Printf("i類型是%T,pi類型是%T,j類型是%T\n",i,pi,j) fmt.Printf("i的值是%v,地址是%p\n",i,&i) fmt.Printf("指針pi的值是%v\n",pi) fmt.Printf("變量j的值是%v,地址是%p\n\n",j,&j)
varc=3+4i pc:=&c //用地址給指針賦值 d:=*pc+2+2i //指針參與計算 fmt.Printf("pc類型是%T,值是%v\n",pc,pc) fmt.Printf("變量c地址是%p\n",&c) fmt.Printf("變量d的值是%v\n",d)}指
針運行結果如圖。指
針2.指針修改與交換(1)指針修改一個變量的指針不能被修改為指向另一個不同類型的變量地址,如:varf=3.1416varp=&f //指向浮點型變量的指針vars="easybooks"p=&s //錯誤,被修改為指向字符串型變量編譯錯誤,輸出信息:cannotuse&s(valueoftype*string)as*float64valueinassignment另外,Go也不支持對指針直接進行運算,如對指針變量的自增(++)和自減(--)都是不被允許的:vars="easybooks"p:=&sp++編譯錯誤,輸出:invalidoperation:p++(non-numerictype*string)vara=200p:=&ap--指
針(2)用指針交換變量利用指針可交換兩個變量,但必須注意,這種交換是“值的交換”而非地址交換,即必須通過一個臨時變量作中介,以“*”分別取出兩指針所指變量的值進行交換,而不能直接交換兩個指針變量,如下:vara,b=3,4
varpa,pb=&a,&bpb,pa=pa,pb //直接交換兩個指針變量println(a,b) //錯誤,輸出34
t:=*pa //t用作臨時變量*pa=*pb*pb=tprintln(a,b) //正確,輸出4302數
組1.數組聲明和初始化2.數組的訪問與遍歷數
組1.數組聲明和初始化(1)數組聲明聲明數組需要指定元素類型及個數(長度),語法格式如下:var數組名[長度]類型例如,聲明一個名為array、包含5個int類型元素的數組,如下:vararray[5]int(2)數組初始化初始化數組可以有兩種寫法:數組名=[n(長度)]類型{元素0,元素1,元素2,...,元素n-1} //寫法一數組名=[...]類型{元素0,元素1,元素2,...,元素n-1} //寫法二說明:第一種寫法指明長度,要注意{}中所羅列的元素個數不能大于[]中的長度值;寫法二使用“...”替代長度值,Go語言會根據{}中實際的元素個數來設置數組的長度。例如:數
組2.數組的訪問與遍歷(1)數組訪問數組元素可以通過索引來訪問,格式為“數組名[索引]”,索引從0開始,第1個元素索引為0,第2個索引為1,……以此類推。【實例2.19】輸入一組(10個)非0整數到一個數組中,求出這一組數的平均值,并分別統計出其中正數和負數的個數。程序代碼如下(array01.go):運行演示如圖。03切
片1.切片的創建2.切片復制與清空3.切片遍歷與修改切
片1.切片的創建創建切片可以通過以下不同的途徑。1)由數組或已存在的切片創建語法格式如下:切片名[開始索引:結束索引]說明:(1)開始索引和結束索引分別對應對象(數組或切片)被切取的起始和結束位置的索引。(2)被切取的元素個數為“結束索引-開始索引”。(3)取出的元素不包含結束索引位置的那一個。(4)如果省略開始索引,則表示從對象開頭一直切取到結束索引位置。(5)如果省略結束索引,則表示從開始索引位置一直切取到整個對象的末尾。(6)如果同時省略開始和結束索引,則創建的切片與原對象完全一樣。切
片例如:vararray[8]intarray=[...]int{2,3,5,7,11,13,17,19}s1:=array[2:6] //對數組的切片fmt.Println(s1) //[571113]fmt.Println(len(s1)) //4
s2:=s1[:2] //對切片的切片(省略開始索引)fmt.Println(s2) //[57]
s3:=array[4:] //省略結束索引fmt.Println(s3) //[11131719]
s3=append(s3,23) //內置append函數對切片追加元素fmt.Println(s3) //[1113171923]s4:=array[:4] //對數組的切片(省略開始索引)fmt.Println(s4) //[2357]s4=append(s4,s3...) //兩個切片合并fmt.Println(s4) //[23571113171923]
s5:=array[:] //同時省略開始和結束索引fmt.Println(s5) //[235711131719]切
片2)用make函數創建Go語言的內置函數make可在內存中開辟一塊連續區域,用于創建新的切片,語法格式如下:var切片名[]類型 //聲明新切片切片名=make([]類型,長度,[容量]) //創建新切片說明:“類型”是切片中的元素類型,“長度”是指為這個類型分配多少個元素,“容量”是可選的,指定預分配的元素數量(通常要大于“長度”值,缺省時與長度相等),設定此參數可提前分配比預定數量更多的內存空間以提高效率、改善性能。程序中可用內置cap函數得到容量值。例如:3)直接定義和初始化語句格式:切片名:=[]類型{元素1,元素2,...,元素n}例如:s:=[]int{1,2,3,4,5,6}切
片2.切片復制與清空(1)切片復制Go語言內置函數copy用于復制一個切片,用法舉例如下:vararray[8]intarray=[...]int{2,3,5,7,11,13,17,19}s0:=array[3:7]fmt.Println(s0) //[7111317]s1:=make([]int,len(s0))copy(s1,s0)fmt.Println(s1) //[7111317]//驗證。修改s1,若s0不隨s1改變,就說明s1的確是s0的一個拷貝s1[0]=2fmt.Println(s1) //[2111317]fmt.Println(s0) //[7111317]切
片(2)切片清空如果把切片的開始和結束索引都設為0,則會將切片清空,清空后的切片可重置新的數據內容,如下:vararray[8]intarray=[...]int{2,3,5,7,11,13,17,19}s:=array[4:]fmt.Println(s) //[11131719]s=s[0:0] //清空切片fmt.Println(s) //[]s=array[:4] //重置新值fmt.Println(s) //[2357]切
片3.切片遍歷與修改切片的遍歷也使用for-range語句,由于切片內部含指向數組的指針,數組與基于它創建的切片實際上共享同一段內存,對切片元素的修改是直接作用于數組上的,故可以通過切片來修改數組。【實例2.21】創建一個數組的切片,遍歷切片并修改其元素,然后查看對應數組內容的變化。程序代碼如下(slice.go):運行結果如圖。04映
射1.映射聲明和創建2.映射的操作映
射1.映射聲明和創建聲明映射需要同時指定鍵和值的類型,語法格式如下:var映射名map[鍵類型]值類型與數組不同,聲明映射不需要指定長度,因為映射是可以根據元素對的個數自動增長的,使用len函數可獲取映射中元素對的數目,未初始化的映射的值是nil。映射有兩種基本的創建方式——直接創建和用make函數創建,如下:varm1map[int]stringm1=map[int]string{1:"Go",2:"Java",3:"C++"}fmt.Println(m1) //map[1:Go2:Java3:C++]m2:=map[string]string{"Sun":"星期日","Mon":"星期一"}fmt.Println(m2) //map[Mon:星期一Sun:星期日]m3:=make(map[string]float32,100) //第2個參數(容量)是可選的m3["王林"]=80m3["程明"]=78.5m3["王燕"]=59fmt.Println(m3) //map[王林:80王燕:59程明:78.5]映
射2.映射的操作對一個映射可進行如下操作:(1)用“映射名[鍵]”訪問指定鍵對應的值。(2)用內置delete函數“delete(映射名,鍵)”刪除某個鍵值對。(3)用如下語句判斷某個鍵是否在映射中:變量1,變量2=映射名[鍵]其中,變量2是布爾型,標識該鍵是否在映射中(在為true,不在為false),在的情況下,變量1可接收到該鍵的值,如果僅想知道鍵是否在映射中而不需要獲取其值,變量1也可不寫,以一個下劃線代替:_,變量2=映射名[鍵]映
射(4)用for-range語句遍歷映射。例如:fmt.Print("王林成績為",m3["王林"])m3["王林"]=85fmt.Println(",修改為
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025攝影器材租賃合同示范文本
- 規范中藥材有效成分性狀標準
- 天津醫科大學《交響音樂賞析》2023-2024學年第二學期期末試卷
- 明達職業技術學院《法語精讀(Ⅱ)》2023-2024學年第一學期期末試卷
- 四川航天職業技術學院《材料失效診斷、預測和預防》2023-2024學年第二學期期末試卷
- 四川國際標榜職業學院《形勢與政策》2023-2024學年第二學期期末試卷
- 廣西壯族自治區河池市羅城仫佬族自治縣重點中學2025屆初三一診小練習二數學試題含解析
- 2025屆北京市海淀區初三下學期六校(4月)聯考數學試題試卷含解析
- 中國石油大學(北京)《公共建筑設計Ⅱ》2023-2024學年第二學期期末試卷
- 云南三鑫職業技術學院《網絡新聞編輯與評論》2023-2024學年第二學期期末試卷
- 臨床診療指南癲癇病學分冊
- 制作沙包(教案)-五年級勞動版
- PI形式發票范文模板
- 同濟大學信紙
- ERwin工具使用培訓課件
- 工作交接表excel模板
- 隨班就讀學生個人檔案
- 硫磺安全技術說明書MSDS
- 孟母三遷成語故事
- 2017年10月自考00015英語二試卷及答案
- 國開電大《工程數學(本)》形成性考核作業5答案
評論
0/150
提交評論