Go語言的學習筆記(第二章)

2021-01-14 編程那些煩心事


Go語言的基本結構
package main // package關鍵字聲明包名

// 導入語句
import "fmt"

/*
函數外只能放置標識符(變量、常量、函數、類型)的聲明
不能放置fmt.Println("Hello World")這樣的語句
*/

// 程序的入口函數,如果你要編譯一個可執行的文件,必須要聲明一個main包,而且一定要有一個main函數
func main() {
fmt.Println("Hello World")
}


變量和常量標識符和關鍵字

標識符

在程式語言中標識符就是程式設計師定義的具有特殊意義的詞,比如變量名、常量名、函數名等等。Go語言中標識符由字母數字和_(下劃線)組成,並且只能以字母和_開頭。舉幾個例子:abc, _, _123, a123。


關鍵字

關鍵字是指程式語言中預先定義好的具有特殊含義的標識符。關鍵字和保留字都不建議用作變量名。

Go語言中有25個關鍵字:

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

此外,Go語言中還有37個保留字:

Constants:    true  false  iota  nil

Types:    int  int8  int16  int32  int64  
         uint  uint8  uint16  uint32  uint64  uintptr
         float32  float64  complex128  complex64
         bool  byte  rune  string  error

Functions:   make  len  cap  new  append  copy  close  delete
            complex  real  imag
            panic  recover


變量

變量的來歷

程序運行過程中的數據都是保存在內存中,我們想要在代碼中操作某個數據時就需要去內存上找到這個變量,但是如果我們直接在代碼中通過內存地址去操作變量的話,代碼的可讀性會非常差而且還容易出錯,所以我們就利用變量將這個數據的內存地址保存起來,以後直接通過這個變量就能找到內存上對應的數據了。


變量類型

變量(Variable)的功能是存儲數據。不同的變量保存的數據類型可能會不一樣。經過半個多世紀的發展,程式語言已經基本形成了一套固定的類型,常見變量的數據類型有:整型、浮點型、布爾型等。

Go語言中的每一個變量都有自己的類型,並且變量必須經過聲明才能開始使用。


變量聲明

Go語言中的變量需要聲明後才能使用,同一作用域內不支持重複聲明。並且Go語言的變量聲明後必須使用

標準聲明:

Go語言的變量聲明格式為:

var 變量名 變量類型

變量聲明以關鍵字var開頭,變量類型放在變量的後面,行尾無需分號。舉個例子:

var name string
var age int
var isOk bool


批量聲明

每聲明一個變量就需要寫var關鍵字會比較繁瑣,go語言中還支持批量變量聲明:

var (
   a string
   b int
   c bool
   d float32
)


變量的初始化

Go語言在聲明變量的時候,會自動對變量對應的內存區域進行初始化操作。每個變量會被初始化成其類型的默認值,例如:整型和浮點型變量的默認值為0。字符串變量的默認值為空字符串。布爾型變量默認為false。切片、函數、指針變量的默認為nil。

當然我們也可在聲明變量的時候為其指定初始值。變量初始化的標準格式如下:

var 變量名 類型 = 表達式

舉個例子:

var name string = "Jerry"
var age int = 18

或者一次初始化多個變量

var name, age = "Jerry", 20


類型推導

有時候我們會將變量的類型省略,這個時候編譯器會根據等號右邊的值來推導變量的類型完成初始化。

var name = "Jerry"
var age = 18


短變量聲明

在函數內部,可以使用更簡略的 := 方式聲明並初始化變量。

package main

import (
"fmt"
)
// 全局變量m
var m = 100

func main() {
n := 10
m := 200 // 此處聲明局部變量m
fmt.Println(m, n)
}


匿名變量

在使用多重賦值時,如果想要忽略某個值,可以使用匿名變量(anonymous variable)。匿名變量用一個下劃線_表示,例如:

func foo() (int, string) {
return 10, "Q1mi"
}
func main() {
x, _ := foo()
_, y := foo()
fmt.Println("x=", x)
fmt.Println("y=", y)
}

匿名變量不佔用命名空間,不會分配內存,所以匿名變量之間不存在重複聲明。(在Lua等程式語言裡,匿名變量也被叫做啞元變量。)

注意事項:

函數外的每個語句都必須以關鍵字開始(var、const、func等)

:=不能使用在函數外。

_多用於佔位,表示忽略值。


常量

相對於變量,常量是恆定不變的值,多用於定義程序運行期間不會改變的那些值。常量的聲明和變量聲明非常類似,只是把var換成了const,常量在定義的時候必須賦值。

const pi = 3.1415
const e = 2.7182

聲明了pi和e這兩個常量之後,在整個程序運行期間它們的值都不能再發生變化了。

多個常量也可以一起聲明:

const (
   pi = 3.1415
   e = 2.7182
)

const同時聲明多個常量時,如果省略了值則表示和上面一行的值相同。例如:

const (
   n1 = 100
   n2
   n3
)

上面示例中,常量n1、n2、n3的值都是100。


iota

iota是go語言的常量計數器,只能在常量的表達式中使用。

iota在const關鍵字出現時將被重置為0。const中每新增一行常量聲明將使iota計數一次(iota可理解為const語句塊中的行索引)。使用iota能簡化定義,在定義枚舉時很有用。

舉個例子:

const (
n1 = iota //0
n2        //1
n3        //2
n4        //3
)


幾個常見的ioda示例

使用_跳過某些值:

const (
n1 = iota //0
n2        //1
_
n4        //3
)

iota聲明中間插隊:

const (
n1 = iota //0
n2 = 100  //100
n3 = iota //2
n4        //3
)
const n5 = iota //0

定義數量級 (這裡的<<表示左移操作,1<<10表示將1的二進位表示向左移10位,也就是由1變成了10000000000,也就是十進位的1024。同理2<<2表示將2的二進位表示向左移2位,也就是由10變成了1000,也就是十進位的8。)

const (
_  = iota
KB = 1 << (10 * iota)
MB = 1 << (10 * iota)
GB = 1 << (10 * iota)
TB = 1 << (10 * iota)
PB = 1 << (10 * iota)
)

多個iota定義在一行:

const (
a, b = iota + 1, iota + 2 //1,2
c, d                      //2,3
e, f                      //3,4
)


Go語言基礎之基本數據類型

Go語言中有豐富的數據類型,除了基本的整型、浮點型、布爾型、字符串外,還有數組、切片、結構體、函數、map、通道(channel)等。Go 語言的基本類型和其他語言大同小異。


基本數據類型

整型分為以下兩個大類:按長度分為:int8、int16、int32、int64 對應的無符號整型:uint8、uint16、uint32、uint64

其中,uint8就是我們熟知的byte型,int16對應C語言中的short型,int64對應C語言中的long型。

類型描述uint8無符號 8位整型 (0 到 255)uint16無符號 16位整型 (0 到 65535)uint32無符號 32位整型 (0 到 4294967295)uint64無符號 64位整型 (0 到 18446744073709551615)int8有符號 8位整型 (-128 到 127)int16有符號 16位整型 (-32768 到 32767)int32有符號 32位整型 (-2147483648 到 2147483647)int64有符號 64位整型 (-9223372036854775808 到 9223372036854775807)


特殊整型

類型描述uint32位作業系統上就是uint32,64位作業系統上就是uint64int32位作業系統上就是int32,64位作業系統上就是int64uintptr無符號整型,用於存放一個指針

注意: 在使用int和 uint類型時,不能假定它是32位或64位的整型,而是考慮int和uint可能在不同平臺上的差異。

注意事項: 獲取對象的長度的內建len()函數返回的長度可以根據不同平臺的字節長度進行變化。實際使用中,切片或 map 的元素數量等都可以用int來表示。在涉及到二進位傳輸、讀寫文件的結構描述時,為了保持文件的結構不會受到不同編譯目標平臺字節長度的影響,不要使用int和 uint。

package main

import "fmt"

func main() {
// 查看變量類型
i1 := 30
fmt.Printf("%T \n", i1) // int

// 聲明int8類型變量
i2 := int8(36) // 明確指定int8類型,否則就是默認為int類型
fmt.Printf("%T \n", i2) // int8
}



八進位&十六進位

Go語言中無法直接定義二進位數,關於八進位和十六進位數的示例如下:

package main

import "fmt"

func main() {
// 十進位
var a = 101 // 類型推導
fmt.Printf("%d \n", a) // 101
fmt.Printf("%b \n", a) // 1100101 佔位符%b表示二進位
fmt.Printf("%o \n", a) // 145 十進位轉成八進位
fmt.Printf("%x \n", a) // 65

// 八進位 以0開頭
b := 077 // 短變量聲明
fmt.Printf("%d \n", b) // 63 八進位轉成十進位

// 十六進位 以0x開頭
var c int = 0x1234567
fmt.Printf("%d \n", c) // 19088743 十六進位轉成十進位
}


浮點型

Go語言支持兩種浮點型數:float32和float64。這兩種浮點型數據格式遵循IEEE 754標準:float32 的浮點數的最大範圍約為 3.4e38,可以使用常量定義:math.MaxFloat32。float64 的浮點數的最大範圍約為 1.8e308,可以使用一個常量定義:math.MaxFloat64。

列印浮點數時,可以使用fmt包配合動詞%f,代碼如下:

package main

import (
       "fmt"
       "math"
)

func main() {
       fmt.Printf("%f\n", math.Pi)
       fmt.Printf("%.2f\n", math.Pi)
}


複數

complex64和complex128

var c1 complex64
c1 = 1 + 2i
var c2 complex128
c2 = 2 + 3i
fmt.Println(c1)
fmt.Println(c2)

複數有實部和虛部,complex64的實部和虛部為32位,complex128的實部和虛部為64位(咱們就放過自己,別去管這玩意了,這東西基本沒咋用到!)。


布爾值

Go語言中以bool類型進行聲明布爾型數據,布爾型數據只有true和false兩個值。

注意:

布爾類型變量的默認值為false。

Go 語言中不允許將整型強制轉換為布爾型.

布爾型無法參與數值運算,也無法與其他類型進行轉換。


字符串

Go語言中的字符串以原生數據類型出現,使用字符串就像使用其他原生數據類型(int、bool、float32、float64 等)一樣。Go 語言裡的字符串的內部實現使用UTF-8編碼。字符串的值為"中的內容,可以在Go語言的源碼中直接添加非ASCII碼字符,例如:

s1 := "hello" // 字符串
s2 := "你好" // 字符串


字符串轉義符

Go 語言的字符串常見轉義符包含回車、換行、單雙引號、制表符等,如下表所示:

轉義符含義\r回車符(返回行首)\n換行符(直接跳到下一行的同列位置)\t制表符\'單引號\"雙引號\\反斜槓

舉個例子,我們要列印一個Windows平臺下的一個文件路徑:

package main

import (
   "fmt"
)

func main() {
   fmt.Println("str := \"c:\\Code\\lesson1\\go.exe\"")
}


多行字符串

Go語言中要定義一個多行字符串時,就必須使用反引號字符:

s1 := `第一行
第二行
第三行
`
fmt.Println(s1)

反引號間換行將被作為字符串中的換行,但是所有的轉義字符均無效,文本將會原樣輸出。


字符串的常用操作

方法介紹len(str)求長度+或fmt.Sprintf拼接字符串strings.Split分割strings.contains判斷是否包含strings.HasPrefix,strings.HasSuffix前綴/後綴判斷strings.Index(),strings.LastIndex()子串出現的位置strings.Join(a[]string, sep string)join操作


byte和rune類型

組成每個字符串的元素叫做「字符」,可以通過遍歷或者單個獲取字符串元素獲得字符。字符用單引號(』)包裹起來,如:

var a := '中'
var b := 'x'

Go 語言的字符有以下兩種:

uint8類型,或者叫 byte 型,代表了ASCII碼的一個字符。

rune類型,代表一個 UTF-8字符。

當需要處理中文、日文或者其他複合字符時,則需要用到rune類型。rune類型實際是一個int32。

Go 使用了特殊的 rune 類型來處理 Unicode,讓基於 Unicode 的文本處理更為方便,也可以使用 byte 型進行默認字符串處理,性能和擴展性都有照顧。

// 遍歷字符串
func traversalString() {
s := "hello你好"
for i := 0; i < len(s); i++ { //byte
fmt.Printf("%v(%c) ", s[i], s[i])
}
fmt.Println()
for _, r := range s { //rune
fmt.Printf("%v(%c) ", r, r)
}
fmt.Println()
}

輸出:

104(h) 101(e) 108(l) 108(l) 111(o) 230(æ) 178(²) 153() 230(æ) 178(²) 179(³) 
104(h) 101(e) 108(l) 108(l) 111(o) 27801(你) 27827(好)

因為UTF8編碼下一個中文漢字由3~4個字節組成,所以我們不能簡單的按照字節去遍歷一個包含中文的字符串,否則就會出現上面輸出中第一行的結果。

字符串底層是一個byte數組,所以可以和[]byte類型相互轉換。字符串是不能修改的 字符串是由byte字節組成,所以字符串的長度是byte字節的長度。rune類型用來表示utf8字符,一個rune字符由一個或多個byte組成。


修改字符串

要修改字符串,需要先將其轉換成[]rune或[]byte,完成後再轉換為string。無論哪種轉換,都會重新分配內存,並複製字節數組。

func changeString() {
s1 := "big"
// 強制類型轉換
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1))

s2 := "白蘿蔔"
runeS2 := []rune(s2)
runeS2[0] = '紅'
fmt.Println(string(runeS2))
}


類型轉換

Go語言中只有強制類型轉換,沒有隱式類型轉換。該語法只能在兩個類型之間支持相互轉換的時候使用。

強制類型轉換的基本語法如下:

T(表達式)

其中,T表示要轉換的類型。表達式包括變量、複雜算子和函數返回值等.

比如計算直角三角形的斜邊長時使用math包的Sqrt()函數,該函數接收的是float64類型的參數,而變量a和b都是int類型的,這個時候就需要將a和b強制類型轉換為float64類型。

func sqrtDemo() {
var a, b = 3, 4
var c int
// math.Sqrt()接收的參數是float64類型,需要強制轉換
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)
}

相關焦點

  • Go語言學習筆記之字符串一
    Go語言是一個年輕人,身上擁有c++,java,python等語言的特點。在網絡通信、並發和並行編程擁有極好的體驗,當然不僅僅在這上上面,還有網絡編程,web應用,應用下載等有著非常大的潛力。這裡列舉一些 Go 語言的特點: 簡化問題,易於學習 內存管理,簡潔語法,易於使用 快速編譯,高效開發 高效執行 並發支持,輕鬆駕馭, 靜態類型 標準類庫,規範統一 易於部署 文檔全面 免費開源學習go語言有幾天了,今天突然想到把學的寫成筆記,記錄一下。如有不正確的請指教。
  • 《王者榮耀》峽谷異聞第二章完成攻略 筆記任務第二章如何完成
    導 讀 王者榮耀筆記任務第二章怎麼做?
  • go 學習筆記之學習函數式編程前不要忘了函數基礎
    所以接下來我們一邊複習一邊學習函數的基本特點,為接下來理解函數式編程打下基礎,關於函數的基礎語言可參考 go 學習筆記之值得特別關注的基礎語法有哪些函數的基礎語法和高級特性下面以最基本四則運算為例,貫穿全文講解函數的基本語法和高級特性
  • 《王者榮耀》筆記任務第二章完成攻略 峽谷異聞任務第二章全攻略
    導 讀 王者榮耀峽谷異聞筆記任務第二章開始了,通過鬼谷子我們可以看到很多的故事在繼續,而且有一些蛛絲馬跡
  • go 學習筆記之解讀什麼是defer延遲函數
    Go 語言中有個 defer 關鍵字,常用於實現延遲函數來保證關鍵代碼的最終執行,常言道: "未雨綢繆方可有備無患".延遲函數就是這麼一種機制,無論程序是正常返回還是異常報錯,只要存在延遲函數都能保證這部分關鍵邏輯最終執行,所以用來做些資源清理等操作再合適不過了.
  • 解密 Go 語言之反射 reflect
    今天是 2020 年的最後一天,讓我們一起繼續愉快的學習吧 :)。在所有的語言中,反射這一功能基本屬於必不可少的模塊。雖說 「反射」 這個詞讓人根深蒂固,但更多的還是 WHY。反射到底是什麼,反射又是基於什麼法則實現的?
  • 王者榮耀峽谷異聞第二階段任務怎麼做 王者榮耀調查筆記第二章任務...
    王者榮耀峽谷異聞第二階段任務怎麼做?王者榮耀在11月3日開放了鬼谷子調查筆記新章節,新階段的任務是讓我們前往地圖查看原初之息劇烈波動的原因。下面就是王者榮耀調查筆記第二章任務攻略了,大家一起來看看吧!
  • go 學習筆記之僅僅需要一個示例就能講清楚什麼閉包
    本篇文章是 Go 語言學習筆記之函數式編程系列文章的第二篇,上一篇介紹了函數基礎,這一篇文章重點介紹函數的重要應用之一: 閉包空談誤國,實幹興邦,以具體代碼示例為基礎講解什麼是閉包以及為什麼需要閉包等問題,下面我們沿用上篇文章的示例代碼開始本文的學習吧!
  • 初一學習方法:做筆記
    做筆記是門很少有人研究的學問。會做筆記的同學可能上課時記得並不多,但很有成效。有些同學的筆記只有自己看得懂,但也很有效。相反,有的同學筆記記得很多,上課時幾乎一直在記筆記,不僅效果差,甚至會影響聽課效果。所以學會有效地做筆記對於每一個同學來說都是很重要的。   1.如何記課堂筆記?
  • 偏微分方程 學習筆記
    有一句話叫做「數學是大自然的語言,而偏微分方程則是大自然的語法」,從此足以看出偏微分方程在自然界中的廣泛應用。無論是工程領域,量子領域,還是金融領域等,都有著偏微分方程的影子。偏微分方程理論研究的發展,更是衍生出了一系列新的研究領域,例如金融工程這一學科,開始獨立於傳統的金融學,就得益於偏微分方程應用到了期權定價當中,從而催生出了現代金融理論。
  • Go 語言的演化歷程 - OSCHINA - 中文開源技術交流社區
    Rob大神在這次分 享中用了兩個生動的例子講述了Golang的演化歷程,總結了Golang到目前為止的成功因素,值得廣大Golang Programmer & Beginner學習和了解。這裡也用了」Golang的演化歷程」作為標題。1、Hello Gophers!
  • 六種版本《道德經》學習筆記:第二十一章
    六種版本《道德經》學習筆記:第二十章(插圖源於網際網路)
  • 濮良貴機械設計第10版複習筆記及詳解——才聰學習網
    [電子書]濮良貴《機械設計》(第10版)筆記和課後習題(含考研真題)詳解本章是濮良貴主編的《機械設計》(第10版)教材的學習輔導書,主要包括以下內容:1.整理名校筆記,濃縮內容精華。在參考了國內外名校名師講授該教材的課堂筆記基礎上,複習筆記部分對該章的重難點進行了整理,因此,本書的內容幾乎濃縮了該教材的知識精華。2.解析課後習題,提供詳盡答案。本書參考了該教材的國內外配套資料和其他教材的相關知識對該教材的課(章)後習題進行了詳細的分析和解答,並對相關重要知識點進行了延伸和歸納。3.挑選考研真題,總結出題思路。
  • 深度學習之用Go語言構建一個屬於自己的神經網絡(附代碼)
    Go語言完全從頭開始構建簡單神經網絡的初學者指南介紹在本文中,我們將完全從頭開始在Golang中構建一個簡單的神經網絡(單層感知器)。我們還將在樣本數據上訓練它並進行一些預測。從頭開始創建自己的神經網絡將會更好地了解神經網絡內部發生的情況,對之後學習算法的工作更加了解。什麼是感知器?感知器由弗蘭克·羅森布拉特於1958 年發明,是最簡單的神經網絡,由n個輸入,一個神經元和一個輸出組成,其中n是數據集的特徵數量。
  • 印象筆記CEO唐毅:用技術創新升級「第二大腦」
    此次烏鎮之行,唐毅還帶來了剛剛入選2019世界網際網路領先科技成果的印象筆記最新技術——「超級筆記」,以及印象筆記出品的首款智能硬體設備——「印象筆」。去年6月,印象筆記宣布重組,從Evernote這家矽谷公司在中國的分支,變成了獨立的「中國網際網路公司」。對於印象筆記的定位,唐毅羅列了四個方面:國人的第二大腦、工具與內容的完美融合、知識和重要信息平臺、知識人群的首屏應用。
  • 半個月學完概率論與數理統計(第二章01)
    接下來我們學習第二章-隨機變量及其分布,內容較多 ,我們分2次來學習。常用的概率分布及其數學期望與方差是我們這一章的重點,考試最喜歡考的,大多都是基礎題,我們必須要拿下。第2.1、2.2節筆記上面看著整一頁圖比較亂,我們來梳理一下,脈絡還是很清晰的。 隨機變量分為離散隨機變量和連續隨機變量。
  • 一根繩上的螞蚱|《自私的基因》13~14 章讀書筆記
    《自私的基因》這本書的讀書筆記有點長,摘抄和想法加起來有 3 萬字。為了方便閱讀,把筆記按章節順序分了五個部分:1~4 章為第一部分,主要講從複製子到生存機器的進化。5~10 章為第二部分,主要講生存機器的不同生存策略。11~15 章每章都是獨立的章節,論述了 5 個不同的問題。
  • 資料| 1800頁33章數學方法精要筆記 —深入數學建模, 機器學習和...
    全書 GitHub 地址:https://github.com/yangyutu/EssentialMath全書總共 33 章分成六個部分:Mathematical Foundations(數學基礎)Mathematical Optimization Methods(數學優化方法)Classical Statistical Methods
  • 中考物理順口溜學習之第三章和第四章筆記匯總
    中考必考考點之物理順口溜匯總,教你輕鬆學物理本次課程我們接著上次課程的內容,來為大家分享一下初二物理第三章和第四章的考點內容,編輯成順口溜,教你輕鬆理解和記憶考點,在中考中拿下好成績。第三章----透鏡及其應用1.透鏡說透鏡,能透光;中間厚,凸透鏡;中間薄,凹透鏡。會聚作用凸透鏡,發散作用凹透鏡。
  • 好人終有好報|《自私的基因》11~12 章讀書筆記
    《自私的基因》這本書的讀書筆記有點長,摘抄和想法加起來有 3 萬字。為了方便閱讀,把筆記按章節順序分了五個部分:1~4 章為第一部分,主要講從複製子到生存機器的進化。5~10 章為第二部分,主要講生存機器的不同生存策略。11~15 章每章都是獨立的章節,論述了 5 個不同的問題。