Go語言程序設計及實例 課件全套 第1-8章 Go語言及編程環境 -Go語言微服務開發入門_第1頁
Go語言程序設計及實例 課件全套 第1-8章 Go語言及編程環境 -Go語言微服務開發入門_第2頁
Go語言程序設計及實例 課件全套 第1-8章 Go語言及編程環境 -Go語言微服務開發入門_第3頁
Go語言程序設計及實例 課件全套 第1-8章 Go語言及編程環境 -Go語言微服務開發入門_第4頁
Go語言程序設計及實例 課件全套 第1-8章 Go語言及編程環境 -Go語言微服務開發入門_第5頁
已閱讀5頁,還剩507頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第1章Go語言及編程環境Go語言簡介01誕生背景誕生背景為應對新時代互聯網的應用程序需要,谷歌的羅伯特·格瑞史莫(RobertGriesemer)、羅布·派克(RobPike)和肯·湯普遜(KenThompson)于2007年9月開始著手設計一種全新的編程語言——Go語言,隨后IanLanceTaylor和RussCox加入該項目,新語言不僅原生支持并發多核編程、極大提升了編譯速度,而且徹底摒棄了傳統語言中很多復雜(并不實用)的語法。Go語言一經推出就廣受歡迎,于2009年11月開放源代碼,并在Linux及MacOSX平臺上進行了實現,后來還追加了Windows系統下的實現。02設計哲學1.少即是多2.世界是組合的3.面向接口編程設計哲學(1)(2)(3)在編程領域也有一個所謂的“二八定律”,即:百分之八十的代碼僅使用到百分之二十的語言特性。可見,單純地增加語言特性并不能保證開發效率的提升,原因是它會增加復雜性,導致程序員更容易犯錯。遵循“二八定律”正如用一個方向盤就可以控制汽車行駛,就沒必要造具有多個方向盤甚至復雜方向變換系統的汽車。例如,Go語言只有for循環,而不像其他語言那樣還有while、dowhile、foreach等多種循環語句,只提供一種方法做事情,把事情做到極致就好。做任何事只提供一種方法幾何上的正交指兩個向量垂直,現實中的正交是指多個因素的一個發生變化,不會影響其他因素。例如,Go語言中的協程、接口、類型系統之間是相互獨立(正交)的,但在編程中通過組合運用這些特性,卻可以極大地提升語言表現力,實現很多復雜的功能。提供正交的語言特性1.少即是多設計哲學2.世界是組合的Go語言的設計者從物質世界的構成模式得到啟發,發現“組合”才是世間萬物最基本最常見的關系,而過往的以“繼承”為基礎的面向對象語言(典型如Java),在對事物的描述上存在根本的缺陷,類和對象更適合表現孤立的單個事物,一旦涉及多個事物間的復雜交互就會出現各種問題,為此Go語言設計者提出“組合優于繼承”的觀點,采用組合的方式來描述對象之間的關系,更貼近真實的自然世界。Go沒有像Java一樣“宗教式”地完全面向對象,而是結合了面向過程、函數式設計及面向對象的優點,其語法元素與C語言有相似之處,用結構體(struct)及其強大的類型系統來構建具有自身特色的面向對象體系,通過函數、接口、類型、閉包等元素的組合,能夠輕松地把大型程序的各個模塊巧妙地銜接運作起來。設計哲學3.面向接口編程Go語言編程是面向接口的,采用一種Duck模型,即類型(類)不再需要顯式地聲明自己實現了哪個(些)接口,接口類型的判斷完全交給底層語言編譯器去處理,這就將接口與其實現徹底地分開,形成了一種“面向接口”的全新編程方式。程序員無須在一開始就精心設計整個系統的接口繼承體系,而是先基于當下具體的某個應用需求局部設計實現一些小的接口,后續再根據需求變化和應用擴展的需要,通過已有接口的自由組合,構造出更抽象、更普適、功能更強的新接口,這使得Go程序的重構非常容易,尤其適合互聯網時代應用快速迭代的開發方式。03優勢特性優勢特性Go的優勢特性主要體現在如下幾個方面。(1)Go的語法十分簡潔,僅僅用了25個關鍵字,是所有主流編程語言中關鍵字最少的。(2)Go語言支持垃圾回收;內置強大的類型系統支持各種復合數據類型,如關聯數組、切片、映射和列表等;內存安全,如內置數組邊界檢查,極大減少越界訪問帶來的安全隱患;還有大量的包和第三方庫的支持。(3)基于類似C的結構體(struct)以組合方式構建的面向對象系統,不僅具備Java對象系統的所有功能,而且對問題域的描述和表現力更強,更貼近客觀真實的世界;內置接口類型,通過接口組合形成新的接口,非侵入式的接口機制徹底解除了接口與實現的耦合,便于快速重構和迭代開發大型應用系統。(4)Go在語言級別原生支持并發,簡化了并發程序設計;基于通道和協程通信的并發機制相比傳統語言的線程機制效率更高,有利于充分發揮多核CPU的威力,為互聯網云時代微服務開發的首選語言。第1章Go語言及編程環境Go語言安裝與使用01平臺與版本平臺與版本Go是跨平臺的編程語言,在各主流操作系統平臺上都有對應的安裝包,訪問官網/dl/(Golang中國)可分別下載到Go在Windows、MacOSX、Linux平臺上的安裝包及源碼,如圖。02Windows平臺安裝Go語言1.下載Go語言編程環境2.安裝Go語言編程環境Windows平臺安裝Go語言1.下載Go語言編程環境在圖的頁面上點擊“MicrosoftWindows”區塊的鏈接下載Go的安裝包,得到的安裝包文件名為go1.20.4.windows-amd64.msi。2.安裝Go語言編程環境(1)雙擊下載得到的安裝包文件,啟動安裝向導如圖,單擊“Next”按鈕。Windows平臺安裝Go語言(2)在“End-UserLicenseAgreement”界面勾選“IacceptthetermsintheLicenseAgreement”接受許可條款,如圖,單擊“Next”按鈕。Windows平臺安裝Go語言(3)在“DestinationFolder”界面設置Go的安裝目錄,這個目錄是作為Go語言環境的GOROOT路徑,通常默認“C:\ProgramFiles\Go”,如圖,單擊“Next”按鈕。Windows平臺安裝Go語言(4)在下一個界面單擊“Install”按鈕開始安裝,界面進度條顯示安裝進度,完成后單擊“Finish”按鈕關閉向導,結束安裝。以管理員身份打開Windows命令行,輸入“goversion”,出現Go的版本信息就表示安裝成功,如圖。03第一個Go程序1.編寫Go程序2.運行Go程序第一個Go程序1.編寫Go程序【實例1.1】編寫第一個Go程序。打開Windows記事本,編寫程序代碼如下(hello.go):packagemain //(a)

import"fmt" //(b)

funcmain(){ //(c) fmt.Printf("Hello,我愛Go語言!@easybooks\n") //(d)}說明:(a)包聲明語句。在所有Go源程序文件頭部都要用一行“package包名”聲明其代碼所屬的包,Go通過包來管理和組織源代碼。(b)包導入語句。“import"包名"”語句導入包,通常Go程序都要像這樣在開頭用一條或多條import語句導入一個或多個需要引用的外部包,可以是Go語言內置標準庫的包,也可以是第三方包或自定義的包。(c)入口函數。用func關鍵字聲明定義一個函數,這里所聲明的main函數是Go程序的入口函數,程序編譯后由此進入開始執行。(d)“fmt.Printf("Hello,我愛Go語言!@easybooks\n")”調用標準輸入/輸出包的Printf函數輸出字符串,要輸出的字符串作為實參傳入Printf函數,必須用雙引號("")括起來,注意這里不能用單引號。第一個Go程序2.運行Go程序在Windows命令行下運行Go程序有兩種方式。(1)gorun命令直接運行gorun命令直接編譯并執行源碼中的main函數。打開命令行,用cd命令進入到GOPATH目錄,輸入命令:gorunhello.go立即看到程序輸出結果。第一個Go程序(2)gobuild命令生成可執行文件運行gobuild命令會先將源碼編譯為可執行(.exe)文件,然后由用戶運行該文件來執行程序。在命令行GOPATH目錄中執行命令:gobuildhello.go待命令執行過后,去到GOPATH目錄下可以看到生成了一個hello.exe文件。運行文件hello.exe,直接輸入:hello.exe輸出同樣的結果。以上兩種方式運行Go程序的過程如圖。第1章Go語言及編程環境Go語言集成開發環境01常用集成開發環境常用集成開發環境可用于Go語言編程的集成開發環境很多,比較常用的如下。(1)GolandGoland是由著名的JetBrains公司推出的一個商業IDE,它整合IntelliJ平臺,提供了針對Go語言的編碼輔助和大量工具集成。(2)LiteIDELiteIDE是由國內開發者做出的一款專門針對Go語言的輕量級開發環境,它基于Qt、Kate和SciTE,包含了跨平臺開發及其它一些必要特性,對代碼編寫、自動補全和運行調試都有很好的支持,同時還包括了對源代碼的抽象語法樹視圖和一些內置工具。(3)SublimeText這是一個跨平臺的文本編輯器,支持編寫非常多的編程語言代碼,它通過一個叫GoSublime的插件來支持Go語言的代碼補全和程序模版創建。(4)GoClipseGoClipse是一個為Eclipse添加Go語言編程功能的插件,通過gocode來實現代碼補全,為初學者創造一個開發Go語言的環境,它依附于著名的Eclipse平臺,可以很容易地享有Eclipse本身所具有的諸多功能。(5)VSCodeVSCode是一款由微軟開發的跨平臺開源代碼編輯器,它使用JSON格式的配置文件進行所有功能和特性的配置,通過擴展程序為編輯器實現語法高亮、參數提示、編譯、調試、文檔生成等各種功能。02GoLand安裝與配置1.安裝2.初始啟動3.項目配置GoLand安裝與配置1.安裝(1)GoLand下載地址/go/,單擊官方主頁上的“Download”按鈕,轉到下載頁,點擊頁面上的“directlink”鏈接下載GoLand安裝包。(2)雙擊下載得到的安裝包goland-2023.1.2.exe,啟動GoLand安裝向導如圖,單擊“Next”按鈕。GoLand安裝與配置(3)在“ChooseInstallLocation”界面設置GoLand安裝目錄,單擊“Next”按鈕。(4)在“InstallationOptions”界面對GoLand安裝選項進行配置,如圖。為方便使用Go語言環境,建議選中全部選項,單擊“Next”按鈕。GoLand安裝與配置(5)在“ChooseStartMenuFolder”界面選擇(命名)要在其中創建程序快捷方式的開始菜單目錄(通常保持默認的“JetBrains”),單擊“Install”按鈕開始安裝,界面進度條顯示安裝進度,完成后在“CompletingGoLandSetup”界面確保選中了“Rebootnow”選項,單擊“Finish”按鈕關閉向導,如圖,系統會自動重啟,使所有的GoLand安裝選項生效。GoLand安裝與配置2.初始啟動(1)GoLand環境支持老用戶使用已有的配置,在初次啟動時會彈出如圖所示的對話框詢問是否導入已有設置,由于筆者計算機是第一次安裝GoLand,選“Donotimportsettings”,單擊“OK”按鈕。GoLand安裝與配置(2)GoLand是商業軟件,需要先激活才能使用。在如左圖所示的界面上選中“ActivateGoLand”、“Activationcode”,于下方文本區粘貼獲取到的激活碼,單擊“Activate”按鈕,激活成功后,在接下來的界面單擊“Continue”,出現歡迎界面如右圖所示。GoLand安裝與配置(3)GoLand界面默認背景是暗黑色,如果不習慣可以進行更改,操作方法是:點選歡迎界面左側“Customize”切換至環境定制選項頁,在“Colortheme”下拉列表中選擇“IntelliJLight”選項,界面背景立刻變為舒適的亮白色,如左圖所示。點選左側“Projects”又切換回歡迎界面,如右圖所示。

GoLand安裝與配置3.項目配置(1)創建Go項目點擊GoLand歡迎界面上的“NewProject”()圖標按鈕創建一個Go項目,出現“NewProject”界面,在“Location”欄設置項目保存路徑及給項目命名。項目默認保存在操作系統當前用戶的GolandProjects目錄下,第一次創建項目時GoLand會自動生成這個目錄,并給項目取默認名awesomeProject,如圖所示。GoLand安裝與配置(2)配置項目的Go環境項目的Go環境通過GOROOT與GOPATH兩個環境變量來配置,之前在安裝使用Go語言的時候對它們的意義已有所提及。GOROOT:Go語言本身(與所使用的開發工具無關)的安裝目錄,通常默認為“C:\ProgramFiles\Go”,當然在安裝Go語言時也可通過向導的“DestinationFolder”界面進行更改。GOPATH:這是Go程序編譯時參考的工作目錄,類似于Java的工作區(Workspace),由用戶自己創建或指定,筆者的是C:\Users\Administrator\go。開發時Go項目所要引用的第三方庫、框架及其他獨立的.go源文件都放在這個目錄(及其子目錄)下,以便Go編譯器能夠找到。GoLand安裝與配置GOPATH則需要用戶來設置,可以在一開始創建項目時就通過點選“NewProject”界面左側“Go(GOPATH)”切換到另一個選項頁界面上去設置GOPATH,也可以在項目創建好后于GoLand集成開發環境中選擇菜單“File”→“Settings...”,打開如圖1.16所示的“Settings”對話框窗口,在左側樹狀導航視圖中選中“Go”→“GOPATH”,在右邊界面“GlobalGOPATH”欄工具條上點擊“Add”()按鈕添加GOPATH路徑條目。03集成開發環境編寫Go程序1.編寫Go程序2.運行Go程序集成開發環境編寫Go程序【實例1.2】在GoLand集成開發環境下編寫和運行第一個Go程序。1.編寫Go程序在GoLand集成開發環境下右擊項目名,選擇“New”→“GoFile”,彈出“NewGoFile”提示用戶輸入文件名,如圖,這里選“Emptyfile”,輸入“hello”直接回車,就在項目中創建了一個Go程序文件hello.go。集成開發環境編寫Go程序GoLand自動打開hello.go文件編輯器,在其中編寫Go程序代碼(或將1.2.3節的程序代碼復制粘貼到編輯器中)保存即可,如圖。集成開發環境編寫Go程序2.運行Go程序在GoLand環境左側項目樹狀視圖中右擊hello.go文件項,彈出菜單選“Run'gobuildhello.go'”或者直接單擊工具欄按鈕運行程序,在開發環境底部出現子窗口顯示運行結果,如圖。第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跳轉語句

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論