Go 語言保證了既能到達靜態編譯語言的安全和性能,又達到了動態語言開發維護的高效率 ,使用一個表達式來形容 Go 語言:Go = C + Python , 說明 Go 語言既有 C 靜態語言程 序的運行速度,又能達到 Python 動態語言的快速開發。java
開發人員在爲項目選擇語言時,不得不在快速開發和性能之間作出選擇。C和C++這類語言提供了很快的執行速度,而 Ruby 和 Python 這類語言則擅長快速開發。Go語言在這二者間架起了橋樑,不只提供了高性能的語言,同時也讓開發更快速。c++
學習曲線平滑git
Go 語言自己包含類C語法、GC機制和經常使用工具,幾乎支持大多數你在其餘語言見過的特性:繼承、重載、對象等.相比較其餘語言(Java,c++), Go入門更加容易程序員
效率高github
Go擁有接近C的運行效率和接近PHP的開發效率,很符合當下軟件開發迭代速度塊,高性能,高效率的特色golang
靜態類型語言,能夠在編譯的時候檢查出來隱藏的大多數問題,又有動態語言的開發效率,有不少的包可使用,寫起來的效率很高web
出身名門編程
Google公司彙集了一批牛人,在各類編程語言稱雄爭霸的局面下推出新的編程語言,天然有它的戰略考慮。並且從Go語言的發展態勢來看,Google對它這個新的寵兒仍是很看重的,Go天然有一個良好的發展前途.windows
自然支持併發數組
語言層面支持併發,這個就是Go最大的特點,天生的支持併發。能夠充分的利用多核,很容易的實現併發
強大的標準庫
包括互聯網應用、系統編程和網絡編程。Go裏面的標準庫基本上已是很是穩定了,特別是我這裏提到的三個,網絡層、系統層的庫很是實用.而且Go提供了軟件生命週期(開發、測試、部署、維護等等)的各個環節的工具,如go tool、gofmt、go test,最大限度確保 Go 程序的穩定性
常見的 Go 開發職位
這裏參考 Go 的官網
docs.studygolang.com/doc/install
Cris 使用的是 Windows 平臺,直接下載 msi 安裝包便可
而後一路安裝 next 便可
安裝完畢後,打開 cmd,而後驗證 Go 的安裝
打開環境變量
打開 cmd 窗口
表示 Go 的開發環境ok
而後設置Go 的開發空間(推薦)
GOPATH 設置以下(表示Go 開發項目的放置路徑)
這裏我的選擇 Visual Studio Code,畢竟以前開發的Python和Shell都使用的這個,感受至關好用
固然還能夠選擇 GoLand 等專門開發 Go 的 IDE
打開 Visual Studio Code,開發一個最簡單的 Go 程序
爲了方便開發,咱們須要爲 Visual Studio Code 安裝一些插件,具體步驟以下
而後將這些插件放到 Go 安裝路徑 /bin 目錄下,接着重啓 Visual Studio Code
開發一個Go 的 hello world 程序 test.go
// Go文件所在包
package main
// 導入 fmt 包,用於格式化輸入,輸出
import "fmt"
// 主函數
func main() {
// 調用函數
fmt.Println("cris")
}
複製代碼
而後執行 go build 命令
還能夠經過 go run 命令直接運行 go 文件(生產環境都是先編譯,後執行)
Go 項目開發路徑整理
注意
關於 Go 的編譯和執行
經常使用的轉義字符
\t: 表示一個製表符,能夠用於排版
\n: 換行符
\\ : \
\r: 回車, \r 後面的內容會依次替換前面的內容
package main
import "fmt"
func main() {
fmt.Println("cris")
fmt.Print("james\n")
fmt.Println("cirs\rhahah") // \r 表示回車但不換行
}
複製代碼
// 行註釋
/* 多行註釋 */
複製代碼
這裏建議使用快捷鍵
設置每行代碼長度
Golang 官方網站 golang.org
Golang 官方標準庫 API 文檔, golang.org/pkg(studygolang.com/pkgdoc) 能夠查看 Golang 全部包下的函數和使用
Golang 中文網站 studygolang.com/
Dos: Disk Operating System 磁盤操做系統.一般在 windows 上程序員偶爾會經過命令的方式來操做系統,例如最多見的 CMD 窗口
dos 操做簡單流程
經常使用 dos 命令
cd : 切換目錄
cd .. : 切換到上一級目錄
cd \ : 切換到根目錄
dir : 查看當前目錄
md 文件夾 : 新建一個文件夾
del 文件 : 刪除文件
rd 空目錄 : 刪除空目錄
rd /q/s 目錄名 : 直接刪除該目錄及如下全部文件和目錄
cp/move 文件 : 複製/移動文件
cls : 清屏
exit : 退出終端
建立空文件
追加/建立有內容的文件
變量表示內存中的一個存儲區域
該區域有本身的名稱(變量名)和類型(數據類型)
Golang 變量使用的三種方式
第一種:指定變量類型,聲明後若不賦值,使用默認值
package main
import "fmt"
func main() {
var a int
fmt.Print("a=", a)
}
複製代碼
根據值自行斷定變量類型(類型推導)
package main
import "fmt"
func main() {
var a = 12
fmt.Print("a=", a)
}
複製代碼
省略 var, 注意 :=左側的變量不該該是已經聲明過的,不然會致使編譯錯誤
package main
import "fmt"
func main() {
a := 12
fmt.Print("a=", a)
}
複製代碼
多變量聲明
在編程中,有時咱們須要一次性聲明多個變量,Golang 也提供這樣的語法
經過手動賦值的方式
func main() {
var name, age = "cris", 12
fmt.Print("name=", name, ",age=", age)
}
複製代碼
經過默認值的方式(多個變量數據類型須要一致)
func main() {
var name, address string
fmt.Print("name=", name, ",address=", address)
}
複製代碼
省略 var 關鍵字
func main() {
name, address := "cris", "重慶"
fmt.Print("name=", name, ",address=", address)
}
複製代碼
一次性聲明多個全局變量【在 go 中函數外部定義變量就是全局變量】
// 定義多個全局變量方式一
var country, city = "中國", "重慶"
// 定義多個全局變量方式二
var (
n1 = 100
n2 = 200
)
複製代碼
該區域的數據值能夠在同一類型範圍內不斷變化(重點)
變量在同一個做用域(在一個函數或者在代碼塊)內不能重名
變量=變量名+值+數據類型,這一點請你們注意,變量的三要素
Golang 的變量若是沒有賦初值,編譯器會使用默認值, 好比 int 默認值 0 string 默認值爲空串, 小數默認爲 0
和 Java 相似,+ 左右兩邊都是數字,則相加;若是有兩個字符串,則拼接
name, address := "james", "江北區"
name = name + "-harden" // james-harden
複製代碼
基本數據類型
複雜數據類型
整數類型(有符號)
整數類型(無符號)
var n uint8 = 256 // constant 256 overflows uint8
fmt.Print(n)
複製代碼
其餘整數類型
整數細節
Golang 各整數類型分:有符號和無符號,int uint 的大小和系統有關
Golang 的整型默認聲明爲 int 型
var i = 123
// i 的數據類型是 int
fmt.Printf("i 的數據類型是 %T", i)
複製代碼
如何在程序查看某個變量的字節大小和數據類型
var i = 2
// i 的數據類型是 int,字節大小是 8
fmt.Printf("i 的數據類型是 %T,字節大小是 %d", i, unsafe.Sizeof(i))
複製代碼
Golang 程序中整型變量在使用時,遵照保小不保大的原則,即:在保證程序正確運行下,儘可能 使用佔用空間小的數據類型。【如:年齡】
bit: 計算機中的最小存儲單位。byte:計算機中基本存儲單元。[二進制再詳細說] 1byte = 8 bit
小數類型就是用於存放小數的,好比 1.2 0.23 -1.911
說明
關於浮點數在機器中存放形式的簡單說明,浮點數=符號位+指數位+尾數位 說明:浮點數都是有符號的.
尾數部分可能丟失,形成精度損失。 -123.0000901
var i float32 = -12.912345678
fmt.Print(i) // -12.912346
複製代碼
說明:float64 的精度比 float32 的要準確. 說明:若是咱們要保存一個精度高的數,則應該選用 float64
浮點型的存儲分爲三部分:符號位+指數位+尾數位 在存儲過程當中,精度會有丟失
使用細節
Golang 浮點類型有固定的範圍和字段長度,不受具體 OS(操做系統)的影響
Golang 的浮點型默認聲明爲 float64 類型
浮點型常量有兩種表示形式
十進制數形式:如:5.12 .512 (必須有小數點) 科學計數法形式:如:5.1234e2 = 5.12 * 10 的 2 次方; 5.12E-2 = 5.12/10 的 2 次方
一般狀況下,應該使用 float64 ,由於它比 float32 更精確。[開發中,推薦使用 float64]
Golang 中沒有專門的字符類型,若是要存儲單個字符(字母),通常使用 byte 來保存。 字符串就是一串固定長度的字符鏈接起來的字符序列。Go 的字符串是由單個字節鏈接起來的。也 就是說對於傳統的字符串是由字符組成的,而 Go 的字符串不一樣,它是由字節組成的
var a byte = '?'
fmt.Print(a) // 97
fmt.Printf("a=%c", a) // ? 若是須要輸出對應的字符,須要格式化
複製代碼
ps :
字符使用細節
字符常量是用單引號('')括起來的單個字符。例如:var c1 byte = 'a' var c2 int = '中' var c3 byte = '9'
Go 中容許使用轉義字符 '\’來將其後的字符轉變爲特殊字符型常量。例如:var c3 char = ‘\n’ ('\n'表示換行符)
Go 語 言 的 字 符 使 用 UTF-8 編 碼 , 如 果 想 查 詢 字 符 對 應 的 utf8 碼 值 www.mytju.com/classcode/t… 英文字母-1 個字節 漢字-3 個字節
在 Go 中,字符的本質是一個整數,直接輸出時,是該字符對應的 UTF-8 編碼的碼值
能夠直接給某個變量賦一個數字,而後按格式化輸出時%c,會輸出該數字對應的 unicode 字符
var a = 22269
fmt.Printf("a=%c", a) // 國
複製代碼
字符類型是能夠進行運算的,至關於一個整數,由於它都對應有 Unicode 碼
var a = 'a'
var b = 10 + a // 10 + 97
fmt.Printf("b=%c", b) // k
複製代碼
字符類型本質探討
字符串就是一串固定長度的字符鏈接起來的字符序列。Go 的字符串是由單個字節鏈接起來的。Go 語言的字符串的字節使用 UTF-8 編碼標識 Unicode 文本
Go 語言的字符串的字節使用 UTF-8 編碼標識 Unicode 文本,這樣 Golang 統一使用 UTF-8 編碼,中文亂碼問題不會再困擾程序員
字符串一旦賦值了,字符串就不能修改了:在 Go 中字符串是不可變的
字符串的兩種表示形式
雙引號, 會識別轉義字符
反引號,以字符串的原生形式輸出,包括換行和特殊字符,能夠實現防止攻擊、輸出源代碼等效果
var name = "james\ncris"
fmt.Print(name)
var name = `james\ncris`
fmt.Print(name) // james\ncris
複製代碼
字符串拼接方式
var str = "james" + "cris"
fmt.Print(str) // jamescris
str += "---"
fmt.Print(str) // jamescris---
複製代碼
在 go 中,數據類型都有一個默認值,當程序員沒有賦值時,就會保留默認值,在 go 中,默認值 又叫零值
數據類型 | 默認值 |
---|---|
整型 | 0 |
浮點型 | 0 |
字符串 | "" |
布爾類型 | false |
var a int
var b float64
var c bool
var str string
fmt.Printf("a=%v,b=%v,c=%v,d=%v", a, b, c, str)
複製代碼
Golang 和 java / c 不一樣,Go 在不一樣類型的變量之間賦值時須要顯式轉換。也就是說 Golang 中數 據類型不能自動轉換
表達式 T(v) 將值 v 轉換爲類型 T T: 就是數據類型,好比 int32,int64,float32 等等 v: 就是須要轉換的變量
var a int16 = 200
var b = int8(a)
var c = float32(a)
// a = 200, b = -56, c = 200
fmt.Printf("a=%v,b=%v,c=%v", a, b, c)
複製代碼
注意
var a int16 = 200
var b = float32(a)
// a:int16,b:float32
fmt.Printf("a:%T,b:%T", a, b)
複製代碼
在 fmt.Printf() 方法中,經常使用的格式化參數:
%T : 表示變量的數據類型
%v : 直接輸出變量的值
%c : byte 數據類型格式化
%q : 爲字符串加上 ""
%t : 布爾格式化
%d : 整數格式化
%f : 浮點數格式化
基本數據類型轉 String 方式一 fmt.Sprintf()
var num = 12
//1. 數字-->字符串
var str = fmt.Sprintf("%d", num)
// str=12,type is string
fmt.Printf("str=%v,type is %T", str, str)
var num = 123
var str = strconv.Itoa(num)
fmt.Printf("%q,%T", str, str)
//2. float-->字符串
var b = 11.1
str = fmt.Sprintf("%f", b)
// str=11.100000,type is string
fmt.Printf("str=%v,type is %T", str, str)
//3. bool-->字符串
var c = false
str = fmt.Sprintf("%t", c)
// str=false,type is string
fmt.Printf("str=%v,type is %T", str, str)
// str="false",type is string(使用 %q 能夠爲字符串加上 "")
fmt.Printf("str=%q,type is %T", str, str)
//4. char-->字符串
var d = 'a'
str = fmt.Sprintf("%c", d)
// str="a",type is string
fmt.Printf("str=%q,type is %T", str, str)
複製代碼
基本數據類型轉 String 方式二
使用 strconv 包的函數
var num = 123
// 10 表示 10 進制
var str = strconv.FormatInt(int64(num), 10)
fmt.Printf("str 類型是 %T,值是 %q", str, str)
var f = 12.2
// 'f' 表示格式 10表示小數位的精度, 64 表示64位float
str = strconv.FormatFloat(f, 'f', 10, 64)
// str 類型是 string,值是 "12.2000000000"
fmt.Printf("str 類型是 %T,值是 %q", str, str)
var b = false
str = strconv.FormatBool(b)
// str 類型是 string,值是 "false"
fmt.Printf("str 類型是 %T,值是 %q", str, str)
複製代碼
String 轉換爲基本數據類型
var str = "true"
// 使用 _ 忽略返回的 error
var b, _ = strconv.ParseBool(str)
// true,bool
fmt.Printf("%t,%T", b, b)
str = "123"
var num, _ = strconv.ParseInt(str, 10, 64)
// 123,int64
fmt.Printf("%d,%T", num, num)
str = "12.2"
var f, _ = strconv.ParseFloat(str, 32)
// 12.200000,float64
fmt.Printf("%f,%T", f, f)
複製代碼
ps : 若是 String 轉換爲基本數據類型,須要確保 String 能夠有效轉換成基本數據類型,例如 "hello" --> 數字(Go 處理爲默認值,0)
基本數據類型內存解析
基本數據類型,變量存的就是值,也叫值類型
獲取變量的地址,用&,好比: var num int, 獲取 num 的地址:&num 分析一下基本數據類型在內存的佈局
var num = 12
// 0xc00006a080
fmt.Print(&num)
複製代碼
指針類型,指針變量存的是一個地址,這個地址指向的空間存的纔是值 好比:var ptr *int = &num
var num = 12
// 0xc0000120a8
fmt.Print(&num)
// 輸出:0xc0000120a8
// ptr 是一個指針變量
// ptr 的類型是 *int
// ptr 指向的內存保存的是 num 的內存地址(ptr 指向的內存還有一個本身的內存)
var ptr *int = &num
fmt.Print(ptr)
// 輸出的是 ptr 的內存地址 : 0xc000096020
fmt.Println(&ptr)
複製代碼
示意圖以下
獲取指針類型所指向的值,使用:*,好比 *ptr 獲取 ptr 指向的內存所保存的另外一塊內存的值
var num = 12
// 0xc0000120a8
fmt.Print(&num)
// 輸出:0xc0000120a8
// ptr 是一個指針變量
// ptr 的類型是 *int
// ptr 指向的內存保存的是 num 的內存地址(ptr 指向的內存還有一個本身的內存)
var ptr *int = &num
fmt.Print(ptr)
// 輸出的是 ptr 的內存地址 : 0xc000096020
fmt.Println(&ptr)
// 輸出 12
fmt.Println(*ptr)
複製代碼
說明
特色
值類型:變量直接存儲值,內存一般在棧中分配
引用類型:變量存儲的是一個地址,這個地址對應的空間才真正存儲數據(值),內存一般在堆 上分配,當沒有任何變量引用這個地址時,該地址對應的數據空間就成爲一個垃圾,由 GC 來回收
命名規則
由 26 個英文字母大小寫,0-9 ,_ 組成
數字不能夠開頭。var num int //ok var 3num int //error
Golang 中嚴格區分大小寫
說明:在 golang 中,num 和 Num 是兩個不一樣的變量
標識符不能包含空格
下劃線"_"自己在 Go 中是一個特殊的標識符,稱爲空標識符。能夠表明任何其它的標識符,但 是它對應的值會被忽略(好比:忽略某個返回值)。因此僅能被做爲佔位符使用,不能做爲標識符使用
不能以系統保留關鍵字做爲標識符(一共有 25 個),好比 break,if 等等...
注意事項
包名:保持 package 的名字和目錄保持一致,儘可能採起有意義的包名,簡短,有意義,不要和 標準庫不要衝突 fmt
變量名、函數名、常量名:採用駝峯法
舉例: var stuName string = 「tom」 形式: xxxYyyyyZzzz ...
若是變量名、函數名、常量名首字母大寫,則能夠被其餘的包訪問;若是首字母小寫,則只能 在本包中使用 ( 注:能夠簡單的理解成,首字母大寫是公開的,首字母小寫是私有的) ,在 golang 沒有 public , private 等關鍵字
包名從 src 目錄下開始寫
系統保留關鍵字
系統預約義標識符
運算符是一種特殊的符號,用以表示數據的運算、賦值和比較等
算術運算符
賦值運算符
比較運算符/關係運算符
邏輯運算符
位運算符
其它運算符
算術運算符是對數值類型的變量進行運算的,好比:加減乘除。在 Go 程序中使用的很是多
示例代碼
var a int = 12
var b int = 5
// 2(整數作除法,結果也是整數)
fmt.Println(a / b)
// 2(取餘)
fmt.Println(a % b)
// 2.5
fmt.Println(10.0 / 4)
var c float32 = 10.0
// 5
fmt.Println(c / 2)
var n float32 = 2.5
// 變量浮點數之間的除法須要注意數據類型
var d = c / n
fmt.Print(d)
// % 的使用 : a % b = a-a/b*b
fmt.Println(10 % 4)
fmt.Println(-10 % 4)
fmt.Println(10 % -4)
fmt.Println(-10 % -4)
var i = 1
i++
fmt.Println("i=",i)
i--
fmt.Println("i=",i)
複製代碼
細節
對於除號 "/",它的整數除和小數除是有區別的:整數之間作除法時,只保留整數部分而捨棄 小數部分。 例如: x := 19/5 ,結果是 3
當對一個數取模時,能夠等價 a%b=a-a/b*b , 這樣咱們能夠看到 取模的一個本質運算
Golang 的自增自減只能當作一個獨立語言使用時,不能這樣使用
var b = a++
var c := a--
複製代碼
Golang 的++ 和 -- 只能寫在變量的後面,不能寫在變量的前面,即:只有 a++ a-- 沒有 ++a --a
Golang 的設計者去掉 c / java 中的 自增自減的容易混淆的寫法,讓 Golang 更加簡潔,統一。(強制性的)
關係運算符的結果都是 bool 型,也就是要麼是 true,要麼是 false
關係表達式 常常用在 if 結構的條件中或循環結構的條件中
示例代碼
var a = 1
var b = 2
fmt.Println(a > b)
fmt.Println(a == b)
fmt.Println(a < b)
複製代碼
用於鏈接多個條件(通常來說就是關係表達式),最終的結果也是一個 bool 值
示例代碼
var a = 2
var b = 3
var c = 4
if a > b && b < c {
fmt.Println("true")
} else {
fmt.Println("false")
}
if a < b || b > c {
fmt.Println("ok")
} else {
fmt.Println("no ok")
}
複製代碼
注意事項
func test() bool {
fmt.Println("test")
return true
}
func main() {
var a = 2
var b = 3
if a < b && test() {
fmt.Println("true")
} else {
fmt.Println("false")
}
if a < b || test() {
fmt.Println("ok")
} else {
fmt.Println("no ok")
}
}
複製代碼
賦值運算符就是將某個運算後的值,賦給指定的變量
二進制部分講解
運算符優先級
二進制部分講解
注意 : Go不支持三元運算符
func main() {
var a = 3
// a的地址符號: 0xc00006a080
fmt.Println("a的地址符號:", &a)
var ptr *int = &a
// ptr 指向的值是: 3
fmt.Println("ptr 指向的值是:", *ptr)
}
複製代碼
在編程中,須要接收用戶輸入的數據,就可使用鍵盤輸入語句來獲取。
案例說明
要求:能夠從控制檯接收用戶信息,【姓名,年齡,薪水, 是否經過考試 】
使用 fmt.Scanln() 獲取
func main() {
var name string
var age byte
var flag bool
fmt.Println("請輸入用戶名字")
fmt.Scanln(&name)
fmt.Println("請輸入用戶年齡")
fmt.Scanln(&age)
fmt.Println("是否經過考試")
fmt.Scanln(&flag)
fmt.Printf("用戶名:%v,用戶年齡:%v,用戶是否經過考試:%v",name,age,flag)
}
複製代碼
使用 fmt.Scanf() 獲取
func main() {
var name string
var age byte
var flag bool
fmt.Println("請輸入你的名字,年齡以及是否經過考試,以空格分隔")
fmt.Scanf("%s %d %t", &name, &age, &flag)
fmt.Printf("用戶名:%v,用戶年齡:%v,用戶是否經過考試:%v", name, age, flag)
}
複製代碼
進制介紹
在 golang 中,不能直接使用二進制來表示一個整數,它沿用了 c 的特色
簡單示例
func main() {
var a = 011
var b = 2
var c = 0x11
// 10
fmt.Printf("%b\n", b)
// 2
fmt.Println("b", b)
// 9
fmt.Println("a", a)
// 17
fmt.Println("c", c)
}
複製代碼
進製圖示
進制轉換
其餘進制轉換成二進制
二進制轉換成十進制
八進制轉換成十進制
十六進制轉換成十進制
十進制轉成二進制
十進制轉成八進制
十進制轉成十六進制
二進制轉其餘進制
二進制轉八進制
二進制轉十六進制
其餘進制轉成二進制
八進制轉成二進制
十六進制轉成二進制
位運算
思考題
func main() {
var a = 1 >> 2
var b = -1 >> 2
var c = 1 << 2
var d = -1 << 2
// a 0 b -1 c 4 d -4
fmt.Println("a", a, "b", b, "c", c, "d", d)
}
複製代碼
func main() {
// 2
fmt.Println(2 & 3)
// 3
fmt.Println(2 | 3)
// 5
fmt.Println(13 & 7)
// 5
fmt.Println(5 | 4)
// -2
fmt.Println(-3 ^ 3)
}
複製代碼
二進制簡要說明
二進制是逢 2 進位的進位制,0、1 是基本算符。現代的電子計算機技術所有采用的是二進制,由於它只使用 0、1 兩個數字符號,很是簡單方便,易於用電子方式實現。計算機內部處理的信息,都是採用二進制數來表示的。二進制(Binary)數用 0和 1 兩個數字及其組合來表示任何數。進位規則是「逢 2 進 1」,數字 1 在不一樣的位上表明不一樣的值, 按從右至左的次序,這個值以二倍遞增
在計算機的內部,運行各類運算時,都是以二進制的方式來運行
原碼、反碼、補碼
位運算規則
Golang 中有 3 個位運算, 分別是」按位與&、按位或|、按位異或^,它們的運算規則是:
示例圖解
示例
a := 1 >> 2 // 0000 0001 =>0000 0000 = 0
c := 1 << 2 // 0000 0001 ==> 0000 0100 => 4