欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語言有哪些類型及怎么表示

本篇內(nèi)容主要講解“go語言有哪些類型及怎么表示”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“go語言有哪些類型及怎么表示”吧!

做網(wǎng)站、網(wǎng)站設(shè)計(jì)中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷成為有效果、有回報(bào)的無錫營(yíng)銷推廣。創(chuàng)新互聯(lián)公司專業(yè)成都網(wǎng)站建設(shè)十余年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。

go語言的類型有布爾型(bool)、整型(int8、byte、int16等)、浮點(diǎn)型(float32、float64)、復(fù)數(shù)類型(complex64、complex128)、字符串、字符型、錯(cuò)誤型、指針、數(shù)組、切片、字典、通道、結(jié)構(gòu)體、接口。浮點(diǎn)類型采用IEEE-754標(biāo)準(zhǔn)的表達(dá)方式;復(fù)數(shù)實(shí)際上由兩個(gè)實(shí)數(shù)(在計(jì)算機(jī)中用浮點(diǎn)數(shù)表示)構(gòu)成,一個(gè)表示實(shí)部,一個(gè)表示虛部。

Go語言的類型

Go語言內(nèi)置以下這些基礎(chǔ)類型:

  • 布爾類型:bool。

  • 整型:int8、byte、int16、int、uint、uintptr等。

  • 浮點(diǎn)類型:float32、float64。

  • 復(fù)數(shù)類型:complex64、complex128。

  • 字符串:string。

  • 字符類型:rune。

  • 錯(cuò)誤類型:error。

此外,Go語言也支持以下這些復(fù)合類型:

  • 指針(pointer)

  • 數(shù)組(array)

  • 切片(slice)

  • 字典(map)

  • 通道(chan)

  • 結(jié)構(gòu)體(struct)

  • 接口(interface)

在這些基礎(chǔ)類型之上Go還封裝了下面這幾種類型

int、uint和uintptr等。這些類型的特點(diǎn)在于使用方便,但使用者不能對(duì)這些類型的長(zhǎng)度做任何假設(shè)。對(duì)于常規(guī)的開發(fā)來說,用int和uint就可以了,沒必要用int8之類明確指定長(zhǎng)度的類型,以免導(dǎo)致移植困難?!鞠嚓P(guān)推薦:Go視頻教程】

布爾類型

Go 語言中以 bool 類型進(jìn)行聲明布爾類型數(shù)據(jù),布爾型數(shù)據(jù)只有 true

和 false 兩個(gè)值,需要注意的是:

  • go 語言中不允許將整型強(qiáng)制轉(zhuǎn)換為布爾型

  • 布爾類型變量默認(rèn)值為 false

  • 布爾型無法參與數(shù)值運(yùn)算,也無法與其他類型進(jìn)行轉(zhuǎn)換

go語言有哪些類型及怎么表示

Go語言中的布爾類型與其他語言基本一致,關(guān)鍵字也為bool,可賦值為預(yù)定義的true和false示例代碼如下:

var v1 bool
v1 = true
v2 := (1 == 2) // v2也會(huì)被推導(dǎo)為bool類型

布爾類型不能接受其他類型的賦值,不支持自動(dòng)或強(qiáng)制的類型轉(zhuǎn)換。
以下的示例是一些錯(cuò)誤的用法,會(huì)導(dǎo)致編譯錯(cuò)誤:

var b bool
b = 1 // 編譯錯(cuò)誤
b = bool(1) // 編譯錯(cuò)誤
以下的用法才是正確的:
var b bool
b = (1!=0) // 編譯正確 
fmt.Println("Result:", b) // 打印結(jié)果為Result: true

整型

整型是所有編程語言里最基礎(chǔ)的數(shù)據(jù)類型。Go語言支持表2-1所示的這些整型類型。

go語言有哪些類型及怎么表示

go語言有哪些類型及怎么表示

go語言有哪些類型及怎么表示

1. 類型表示

需要注意的是,int和int32在Go語言里被認(rèn)為是兩種不同的類型,編譯器也不會(huì)幫你自動(dòng)做類型轉(zhuǎn)換,比如以下的例子會(huì)有編譯錯(cuò)誤:

var value2 int32
value1 := 64 // value1將會(huì)被自動(dòng)推導(dǎo)為int類型
value2 = value1 // 編譯錯(cuò)誤

編譯錯(cuò)誤類似于:

cannot use value1 (type int) as type int32 in assignment

使用強(qiáng)制類型轉(zhuǎn)換可以解決這個(gè)編譯錯(cuò)誤:

value2 = int32(value1) // 編譯通過

當(dāng)然,開發(fā)者在做強(qiáng)制類型轉(zhuǎn)換時(shí),需要注意數(shù)據(jù)長(zhǎng)度被截短而發(fā)生的數(shù)據(jù)精度損失(比如將浮點(diǎn)數(shù)強(qiáng)制轉(zhuǎn)為整數(shù))和值溢出(值超過轉(zhuǎn)換的目標(biāo)類型的值范圍時(shí))問題。

類型轉(zhuǎn)換

Go 語言中只有強(qiáng)類型轉(zhuǎn)換,沒有隱式轉(zhuǎn)換。該語法只能在兩個(gè)類型
之間支持相互轉(zhuǎn)換的時(shí)候使用。強(qiáng)制轉(zhuǎn)換的語法如下:

go語言有哪些類型及怎么表示

示例如下:

go語言有哪些類型及怎么表示

2. 數(shù)值運(yùn)算

Go語言支持下面的常規(guī)整數(shù)運(yùn)算:+、-、*、/和%

加減乘除就不詳細(xì)解釋了,需要說下的是,% 和在C語言中一樣是求余運(yùn)算,比如:

5 % 3 // 結(jié)果為:2

3. 比較運(yùn)算

Go語言支持以下的幾種比較運(yùn)算符:>、<、==、>=、<=和!=

這一點(diǎn)與大多數(shù)其他語言相同,與C語言完全一致。

下面為條件判斷語句的例子:

i, j := 1, 2 
if i == j { 
 fmt.Println("i and j are equal.") 
}

兩個(gè)不同類型的整型數(shù)不能直接比較,比如int8類型的數(shù)和int類型的數(shù)不能直接比較,但各種類型的整型變量都可以直接與字面常量(literal)進(jìn)行比較,比如

var i int32
var j int64
i, j = 1, 2 
if i == j { // 編譯錯(cuò)誤
 fmt.Println("i and j are equal.") 
} 
if i == 1 || j == 2 { // 編譯通過
 fmt.Println("i and j are equal.") 
}

4. 位運(yùn)算

Go語言支持表2-2所示的位運(yùn)算符。

go語言有哪些類型及怎么表示

Go語言的大多數(shù)位運(yùn)算符與C語言都比較類似,除了取反在C語言中是~x,而在Go語言中是^x。

編程語言中表示固定值的符號(hào)叫做字面量常量,簡(jiǎn)稱字面量。如整形

字面量八進(jìn)制:“012”或者“0o17”,十六進(jìn)制: “0x12”,二進(jìn)制:”0b101”,

輸出表示如下圖:

go語言有哪些類型及怎么表示

浮點(diǎn)型

字面量八進(jìn)制:“012”或者“0o17”,十六進(jìn)制: “0x12”,二進(jìn)制:”0b101”,
輸出表示如下圖:
浮點(diǎn)型用于表示包含小數(shù)點(diǎn)的數(shù)據(jù),比如1.234就是一個(gè)浮點(diǎn)型數(shù)據(jù)。Go語言中的浮點(diǎn)類型采用IEEE-754標(biāo)準(zhǔn)的表達(dá)方式

1. 浮點(diǎn)數(shù)表示

Go語言定義了兩個(gè)類型float32和float64,其中float32等價(jià)于C語言的float類型,float64等價(jià)于C語言的double類型

go語言有哪些類型及怎么表示

在Go語言里,定義一個(gè)浮點(diǎn)數(shù)變量的代碼如下:

var fvalue1 float32
fvalue1 = 12 
fvalue2 := 12.0 // 如果不加小數(shù)點(diǎn),fvalue2會(huì)被推導(dǎo)為整型而不是浮點(diǎn)型

對(duì)于以上例子中類型被自動(dòng)推導(dǎo)的fvalue2,需要注意的是其類型將被自動(dòng)設(shè)為float64,而不管賦給它的數(shù)字是否是用32位長(zhǎng)度表示的。因此,對(duì)于以上的例子,下面的賦值將導(dǎo)致編譯錯(cuò)誤:

fvalue1 = fvalue2

而必須使用這樣的強(qiáng)制類型轉(zhuǎn)換:

fvalue1 = float32(fvalue2)

2. 浮點(diǎn)數(shù)比較

因?yàn)楦↑c(diǎn)數(shù)不是一種精確的表達(dá)方式,所以像整型那樣直接用==來判斷兩個(gè)浮點(diǎn)數(shù)是否相等是不可行的,這可能會(huì)導(dǎo)致不穩(wěn)定的結(jié)果
下面是一種推薦的替代方案:

import "math" 
// p為用戶自定義的比較精度,比如0.00001 
func IsEqual(f1, f2, p float64) bool { 
 return math.Fdim(f1, f2) < p 
}

復(fù)數(shù)類型

復(fù)數(shù)實(shí)際上由兩個(gè)實(shí)數(shù)(在計(jì)算機(jī)中用浮點(diǎn)數(shù)表示)構(gòu)成,一個(gè)表示實(shí)部(real),一個(gè)表示虛部(imag)。如果了解了數(shù)學(xué)上的復(fù)數(shù)是怎么回事,那么Go語言的復(fù)數(shù)就非常容易理解了。

復(fù)數(shù)有實(shí)部和虛部,complex64 的實(shí)部和虛部為 32 位,complex128的實(shí)部和虛部為 64 位。

go語言有哪些類型及怎么表示

1. 復(fù)數(shù)表示

復(fù)數(shù)表示的示例如下:

var value1 complex64 // 由2個(gè)float32構(gòu)成的復(fù)數(shù)類型
value1 = 3.2 + 12i 
value2 := 3.2 + 12i // value2是complex128類型
value3 := complex(3.2, 12) // value3結(jié)果同 value2

2. 實(shí)部與虛部

對(duì)于一個(gè)復(fù)數(shù)z = complex(x, y),就可以通過Go語言內(nèi)置函數(shù)real(z)獲得該復(fù)數(shù)的實(shí)部,也就是x,通過imag(z)獲得該復(fù)數(shù)的虛部,也就是y。

字符串

Go 語言中的字符串以原生數(shù)據(jù)類型出現(xiàn),使用字符串就像使用其他

原生數(shù)據(jù)類型一樣。Go 語言里的字符串的內(nèi)部實(shí)現(xiàn)使用 utf-8 編碼。字符串的值為雙引號(hào)中的內(nèi)容,如

go語言有哪些類型及怎么表示

在Go語言中,字符串也是一種基本類型。相比之下, C/C++語言中并不存在原生的字符類型,通常使用字符數(shù)組來表示,并以字符指針來傳遞。

Go語言中字符串的聲明和初始化非常簡(jiǎn)單,舉例如下:

var str string // 聲明一個(gè)字符串變量
str = "Hello world" // 字符串賦值
ch := str[0] // 取字符串的第一個(gè)字符
fmt.Printf("The length of \"%s\" is %d \n", str, len(str)) 
fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)

輸出結(jié)果為:

The length of "Hello world" is 11 
The first character of "Hello world" is H.

字符串的內(nèi)容可以用類似于數(shù)組下標(biāo)的方式獲取,但與數(shù)組不同,字符串的內(nèi)容不能在初始化后被修改,比如以下的例子:

str := "Hello world" // 字符串也支持聲明時(shí)進(jìn)行初始化的做法
str[0] = 'X' // 編譯錯(cuò)誤

編譯器會(huì)報(bào)類似如下的錯(cuò)誤:

cannot assign to str[0]

在這個(gè)例子中我們使用了一個(gè)Go語言內(nèi)置的函數(shù)len()來取字符串的長(zhǎng)度。這個(gè)函數(shù)非常有用,我們?cè)趯?shí)際開發(fā)過程中處理字符串、數(shù)組和切片時(shí)將會(huì)經(jīng)常用到。

Printf()函數(shù)的用法與C語言運(yùn)行庫中的printf()函數(shù)如出一轍。

Go編譯器支持UTF-8的源代碼文件格式。這意味著源代碼中的字符串可以包含非ANSI的字符,比如“Hello world. 你好,世界!”可以出現(xiàn)在Go代碼中。但需要注意的是,如果你的Go代碼需要包含非ANSI字符,保存源文件時(shí)請(qǐng)注意編碼格式必須選擇UTF-8。特別是在Windows下一般編輯器都默認(rèn)存為本地編碼,比如中國(guó)地區(qū)可能是GBK編碼而不是UTF-8,如果沒注意這點(diǎn)在編譯和運(yùn)行時(shí)就會(huì)出現(xiàn)一些意料之外的情況。

字符串的編碼轉(zhuǎn)換是處理文本文檔(比如TXT、XML、HTML等)非常常見的需求,不過可惜的是Go語言僅支持UTF-8和Unicode編碼。對(duì)于其他編碼,Go語言標(biāo)準(zhǔn)庫并沒有內(nèi)置的編碼轉(zhuǎn)換支持。不過,所幸的是我們可以很容易基于iconv庫用Cgo包裝一個(gè)。這里有一個(gè)開源項(xiàng)目:https://github.com/xushiwei/go-iconv。

1. 字符串操作

平時(shí)常用的字符串操作如表2-3所示。
go語言有哪些類型及怎么表示
更多的字符串操作,請(qǐng)參考標(biāo)準(zhǔn)庫strings包。

2. 字符串遍歷

Go語言支持兩種方式遍歷字符串。一種是以字節(jié)數(shù)組的方式遍歷:

str := "Hello,世界"n := len(str) for i := 0; i < n; i++ { 
 ch := str[i] // 依據(jù)下標(biāo)取字符串中的字符,類型為byte 
 fmt.Println(i, ch) }

這個(gè)例子的輸出結(jié)果為:

0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 228 8 184 9 150 10 231 11 149 12 140

可以看出,這個(gè)字符串長(zhǎng)度為13。盡管從直觀上來說,這個(gè)字符串應(yīng)該只有9個(gè)字符。這是因?yàn)槊總€(gè)中文字符在UTF-8中占3個(gè)字節(jié),而不是1個(gè)字節(jié)

另一種是以Unicode字符遍歷:

str := "Hello,世界"for i, ch := range str { 
 fmt.Println(i, ch)//ch的類型為rune }

輸出結(jié)果為:

0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 19990 10 30028

以Unicode字符方式遍歷時(shí),每個(gè)字符的類型是rune(早期的Go語言用int類型表示Unicode字符),而不是byte。

字符串的常見操作

go語言有哪些類型及怎么表示

字符類型

在Go語言中支持兩個(gè)字符類型,一個(gè)是byte(實(shí)際上是uint8的別名),代表UTF-8字符串的單個(gè)字節(jié)的值;另一個(gè)是rune,代表單個(gè)Unicode字符。

關(guān)于rune相關(guān)的操作,可查閱Go標(biāo)準(zhǔn)庫的unicode包。另外unicode/utf8包也提供了UTF8和Unicode之間的轉(zhuǎn)換。

出于簡(jiǎn)化語言的考慮,Go語言的多數(shù)API都假設(shè)字符串為UTF-8編碼。盡管Unicode字符在標(biāo)準(zhǔn)庫中有支持,但實(shí)際上較少使用。

byte 和 rune 類型

字符指類字形單位或符號(hào),包括字母、數(shù)字、運(yùn)算符號(hào)、標(biāo)點(diǎn)符

號(hào)和其他符號(hào),以及一些功能性符號(hào)。每個(gè)字符在計(jì)算機(jī)中都有相應(yīng)的二進(jìn)制代碼

go語言有哪些類型及怎么表示

Go 語言內(nèi)置兩種字符類型:

  • 一種是 byte 的字節(jié)類型,它是 uint8 的別名。

  • 另一種是 Unicode 編碼的 rune 類型,它是 int32 類型的別名。

Go 語言默認(rèn)的字符編碼就是 UTF-8 類型的。

遍歷字符串

如下:

go語言有哪些類型及怎么表示

UTF-8 編碼下一個(gè)中文漢字由 3-4 個(gè)字節(jié)組成,所以我們不能簡(jiǎn)
單的按照字節(jié)去遍歷一個(gè)包含中文字符的字符串。
字符串底層是一個(gè) byte 數(shù)組,所以可以和[]byte 類型相互轉(zhuǎn)換。
字符串是不能修改的,字符串由 byte 字節(jié)組成,所以字符串的長(zhǎng)度
就是 byte 字節(jié)的長(zhǎng)度。rune 類型用來表示 utf-8 字符,一個(gè) rune 字
符由一個(gè)或多個(gè) byte 組成。

修改字符串

要修改字符串,需要先將其轉(zhuǎn)換成[]rune 或者[]byte,修改以后,再轉(zhuǎn)換為 string。

無論哪種轉(zhuǎn)換,都會(huì)重新分配內(nèi)存并復(fù)制字節(jié)數(shù)組。如下:

go語言有哪些類型及怎么表示

常見的轉(zhuǎn)義字符

go語言有哪些類型及怎么表示

多行字符串的顯示,可以使用反引號(hào)進(jìn)行,需要注意的是反引號(hào)間換行將被作為字符串中的換行,但是所有的轉(zhuǎn)義字符均無效,文本將會(huì)原樣輸出

go語言有哪些類型及怎么表示

數(shù)組

數(shù)組是Go語言編程中最常用的數(shù)據(jù)結(jié)構(gòu)之一。顧名思義,數(shù)組就是指一系列同一類型數(shù)據(jù)的集合。數(shù)組中包含的每個(gè)數(shù)據(jù)被稱為數(shù)組元素(element),一個(gè)數(shù)組包含的元素個(gè)數(shù)被稱為數(shù)組的長(zhǎng)度。

以下為一些常規(guī)的數(shù)組聲明方法:

[32]byte // 長(zhǎng)度為32的數(shù)組,每個(gè)元素為一個(gè)字節(jié)
[2*N] struct { x, y int32 } // 復(fù)雜類型數(shù)組
[1000]*float64 // 指針數(shù)組
[3][5]int // 二維數(shù)組
[2][2][2]float64 // 等同于[2]([2]([2]float64))

從以上類型也可以看出,數(shù)組可以是多維的,比如[3][5]int就表達(dá)了一個(gè)3行5列的二維整型數(shù)組,總共可以存放15個(gè)整型元素。
在Go語言中,數(shù)組長(zhǎng)度在定義后就不可更改,在聲明時(shí)長(zhǎng)度可以為一個(gè)常量或者一個(gè)常量表達(dá)式(常量表達(dá)式是指在編譯期即可計(jì)算結(jié)果的表達(dá)式)。數(shù)組的長(zhǎng)度是該數(shù)組類型的一個(gè)內(nèi)置常量,可以用Go語言的內(nèi)置函數(shù)len()來獲取。

下面是一個(gè)獲取數(shù)組arr元素個(gè)數(shù)的寫法:

arrLength := len(arr)

1. 元素訪問

可以使用數(shù)組下標(biāo)來訪問數(shù)組中的元素。與C語言相同,數(shù)組下標(biāo)從0開始,len(array)-1則表示最后一個(gè)元素的下標(biāo)。下面的示例遍歷整型數(shù)組并逐個(gè)打印元素內(nèi)容:

for i := 0; i < len(array); i++ { 
 fmt.Println("Element", i, "of array is", array[i]) 
}

Go語言還提供了一個(gè)關(guān)鍵字range,用于便捷地遍歷容器中的元素。當(dāng)然,數(shù)組也是range的支持范圍。上面的遍歷過程可以簡(jiǎn)化為如下的寫法:

for i, v := range array { 
 fmt.Println("Array element[", i, "]=", v) 
}

在上面的例子里可以看到

range具有兩個(gè)返回值,第一個(gè)返回值是元素的數(shù)組下標(biāo),第二個(gè)返回值是元素的值。

2. 值類型

需要特別注意的是,在Go語言中數(shù)組是一個(gè)值類型(value type)。所有的值類型變量在賦值和作為參數(shù)傳遞時(shí)都將產(chǎn)生一次復(fù)制動(dòng)作。

如果將數(shù)組作為函數(shù)的參數(shù)類型,則在函數(shù)調(diào)用時(shí)該參數(shù)將發(fā)生數(shù)據(jù)復(fù)制。因此,在函數(shù)體中無法修改傳入的數(shù)組的內(nèi)容,因?yàn)楹瘮?shù)內(nèi)操作的只是所傳入數(shù)組的一個(gè)副本。

下面用例子來說明這一特點(diǎn):

package main 
import "fmt" 
func modify(array [10]int) { 
 array[0] = 10 // 試圖修改數(shù)組的第一個(gè)元素
 fmt.Println("In modify(), array values:", array) 
} 
func main() { 
 array := [5]int{1,2,3,4,5} // 定義并初始化一個(gè)數(shù)組
 modify(array) // 傳遞給一個(gè)函數(shù),并試圖在函數(shù)體內(nèi)修改這個(gè)數(shù)組內(nèi)容
 fmt.Println("In main(), array values:", array) 
}

該程序的執(zhí)行結(jié)果為:

In modify(), array values: [10 2 3 4 5] 
In main(), array values: [1 2 3 4 5]

從執(zhí)行結(jié)果可以看出,函數(shù)modify()內(nèi)操作的那個(gè)數(shù)組跟main()中傳入的數(shù)組是兩個(gè)不同的實(shí)例。

數(shù)組切片

我們已經(jīng)提過數(shù)組的特點(diǎn):數(shù)組的長(zhǎng)度在定義之后無法再次修改;數(shù)組是值類型,每次傳遞都將產(chǎn)生一份副本。顯然這種數(shù)據(jù)結(jié)構(gòu)無法完全滿足開發(fā)者的真實(shí)需求。

不用失望,Go語言提供了數(shù)組切片(slice)這個(gè)非??岬墓δ軄韽浹a(bǔ)數(shù)組的不足。

初看起來,數(shù)組切片就像一個(gè)指向數(shù)組的指針,實(shí)際上它擁有自己的數(shù)據(jù)結(jié)構(gòu),而不僅僅是個(gè)指針。

數(shù)組切片的數(shù)據(jù)結(jié)構(gòu)可以抽象為以下3個(gè)變量:

  • 一個(gè)指向原生數(shù)組的指針;

  • 數(shù)組切片中的元素個(gè)數(shù);

  • 數(shù)組切片已分配的存儲(chǔ)空間。

從底層實(shí)現(xiàn)的角度來看,數(shù)組切片實(shí)際上仍然使用數(shù)組來管理元素,因此它們之間的關(guān)系讓C++程序員們很容易聯(lián)想起STL中std::vector和數(shù)組的關(guān)系?;跀?shù)組,數(shù)組切片添加了一系列管理功能,可以隨時(shí)動(dòng)態(tài)擴(kuò)充存放空間,并且可以被隨意傳遞而不會(huì)導(dǎo)致所管理的元素被重復(fù)復(fù)制。

1. 創(chuàng)建數(shù)組切片

創(chuàng)建數(shù)組切片的方法主要有兩種——基于數(shù)組和直接創(chuàng)建,下面我們來簡(jiǎn)要介紹一下這兩種方法。

  • 基于數(shù)組

數(shù)組切片可以基于一個(gè)已存在的數(shù)組創(chuàng)建。數(shù)組切片可以只使用數(shù)組的一部分元素或者整個(gè)數(shù)組來創(chuàng)建,甚至可以創(chuàng)建一個(gè)比所基于的數(shù)組還要大的數(shù)組切片。代碼清單2-1演示了如何基于一個(gè)數(shù)組的前5個(gè)元素創(chuàng)建一個(gè)數(shù)組切片。

代碼清單2-1 slice.go

package main 
import "fmt" 
func main() { 
 // 先定義一個(gè)數(shù)組
 var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 
 // 基于數(shù)組創(chuàng)建一個(gè)數(shù)組切片
 var mySlice []int = myArray[:5] 
 fmt.Println("Elements of myArray: ") 
 for _, v := range myArray { 
 fmt.Print(v, " ") 
 } 
 fmt.Println("\nElements of mySlice: ") 
 for _, v := range mySlice { 
 fmt.Print(v, " ") 
 } 
 fmt.Println() 
}

運(yùn)行結(jié)果為:

Elements of myArray: 
1 2 3 4 5 6 7 8 9 10 
Elements of mySlice: 
1 2 3 4 5

Go語言支持用myArray[first:last]這樣的方式來基于數(shù)組生成一個(gè)數(shù)組切片,而且這個(gè)用法還很靈活,比如下面幾種都是合法的。

基于myArray的所有元素創(chuàng)建數(shù)組切片:

mySlice = myArray[:]

基于myArray的前5個(gè)元素創(chuàng)建數(shù)組切片:

mySlice = myArray[:5]

基于從第5個(gè)元素開始的所有元素創(chuàng)建數(shù)組切片:

mySlice = myArray[5:]

  • 直接創(chuàng)建

并非一定要事先準(zhǔn)備一個(gè)數(shù)組才能創(chuàng)建數(shù)組切片。Go語言提供的內(nèi)置函數(shù)make()可以用于靈活地創(chuàng)建數(shù)組切片。下面的例子示范了直接創(chuàng)建數(shù)組切片的各種方法。

創(chuàng)建一個(gè)初始元素個(gè)數(shù)為5的數(shù)組切片,元素初始值為0:

mySlice1 := make([]int, 5)

創(chuàng)建一個(gè)初始元素個(gè)數(shù)為5的數(shù)組切片,元素初始值為0,并預(yù)留10個(gè)元素的存儲(chǔ)空間:

mySlice2 := make([]int, 5, 10)

直接創(chuàng)建并初始化包含5個(gè)元素的數(shù)組切片:

mySlice3 := []int{1, 2, 3, 4, 5}

當(dāng)然,事實(shí)上還會(huì)有一個(gè)匿名數(shù)組被創(chuàng)建出來,只是不需要我們來操心而已。

2. 元素遍歷

操作數(shù)組元素的所有方法都適用于數(shù)組切片,比如數(shù)組切片也可以按下標(biāo)讀寫元素,用len()函數(shù)獲取元素個(gè)數(shù),并支持使用range關(guān)鍵字來快速遍歷所有元素。

傳統(tǒng)的元素遍歷方法如下:

for i := 0; i <len(mySlice); i++ { 
 fmt.Println("mySlice[", i, "] =", mySlice[i]) 
}

使用range關(guān)鍵字可以讓遍歷代碼顯得更整潔。range表達(dá)式有兩個(gè)返回值,第一個(gè)是索引,第二個(gè)是元素的值:

for i, v := range mySlice { 
 fmt.Println("mySlice[", i, "] =", v) 
}

對(duì)比上面的兩個(gè)方法,我們可以很容易地看出使用range的代碼更簡(jiǎn)單易懂。

3. 動(dòng)態(tài)增減元素

可動(dòng)態(tài)增減元素是數(shù)組切片比數(shù)組更為強(qiáng)大的功能。與數(shù)組相比,數(shù)組切片多了一個(gè)存儲(chǔ)能力(capacity)的概念,即元素個(gè)數(shù)和分配的空間可以是兩個(gè)不同的值。合理地設(shè)置存儲(chǔ)能力的值,可以大幅降低數(shù)組切片內(nèi)部重新分配內(nèi)存和搬送內(nèi)存塊的頻率,從而大大提高程序性能。

假如你明確知道當(dāng)前創(chuàng)建的數(shù)組切片最多可能需要存儲(chǔ)的元素個(gè)數(shù)為50,那么如果你設(shè)置的存儲(chǔ)能力小于50,比如20,那么在元素超過20時(shí),底層將會(huì)發(fā)生至少一次這樣的動(dòng)作——重新分配一塊“夠大”的內(nèi)存,并且需要把內(nèi)容從原來的內(nèi)存塊復(fù)制到新分配的內(nèi)存塊,這會(huì)產(chǎn)生比較明顯的開銷。給“夠大”這兩個(gè)字加上引號(hào)的原因是系統(tǒng)并不知道多大才是夠大,所以只是一個(gè)簡(jiǎn)單的猜測(cè)。比如,將原有的內(nèi)存空間擴(kuò)大兩倍,但兩倍并不一定夠,所以之前提到的內(nèi)存重新分配和內(nèi)容復(fù)制的過程很有可能發(fā)生多次,從而明顯降低系統(tǒng)的整體性能。但如果你知道最大是50并且一開始就設(shè)置存儲(chǔ)能力為50,那么之后就不會(huì)發(fā)生這樣非常耗費(fèi)CPU的動(dòng)作,從而達(dá)到空間換時(shí)間的效果。

數(shù)組切片支持Go語言內(nèi)置的cap()函數(shù)和len()函數(shù),代碼清單2-2簡(jiǎn)單示范了這兩個(gè)內(nèi)置函數(shù)的用法??梢钥闯?,cap()函數(shù)返回的是數(shù)組切片分配的空間大小,而len()函數(shù)返回的是數(shù)組切片中當(dāng)前所存儲(chǔ)的元素個(gè)數(shù)。

代碼清單2-2 slice2.go

package main 
import "fmt" 
func main() { 
 mySlice := make([]int, 5, 10) 
 fmt.Println("len(mySlice):", len(mySlice)) 
 fmt.Println("cap(mySlice):", cap(mySlice)) 
}

該程序的輸出結(jié)果為:

len(mySlice): 5 
cap(mySlice): 10

如果需要往上例中mySlice已包含的5個(gè)元素后面繼續(xù)新增元素,可以使用append()函數(shù)。
下面的代碼可以從尾端給mySlice加上3個(gè)元素,從而生成一個(gè)新的數(shù)組切片:

mySlice = append(mySlice, 1, 2, 3)

函數(shù)append()的第二個(gè)參數(shù)其實(shí)是一個(gè)不定參數(shù),我們可以按自己需求添加若干個(gè)元素,甚至直接將一個(gè)數(shù)組切片追加到另一個(gè)數(shù)組切片的末尾:

mySlice2 := []int{8, 9, 10} 
// 給mySlice后面添加另一個(gè)數(shù)組切片
mySlice = append(mySlice, mySlice2...)

需要注意的是,我們?cè)诘诙€(gè)參數(shù)mySlice2后面加了三個(gè)點(diǎn),即一個(gè)省略號(hào),如果沒有這個(gè)省略號(hào)的話,會(huì)有編譯錯(cuò)誤,因?yàn)榘碼ppend()的語義,從第二個(gè)參數(shù)起的所有參數(shù)都是待附加的元素。因?yàn)閙ySlice中的元素類型為int,所以直接傳遞mySlice2是行不通的。加上省略號(hào)相當(dāng)于把mySlice2包含的所有元素打散后傳入。

上述調(diào)用等同于:

mySlice = append(mySlice, 8, 9, 10)

數(shù)組切片會(huì)自動(dòng)處理存儲(chǔ)空間不足的問題。如果追加的內(nèi)容長(zhǎng)度超過當(dāng)前已分配的存儲(chǔ)空間(即cap()調(diào)用返回的信息),數(shù)組切片會(huì)自動(dòng)分配一塊足夠大的內(nèi)存。

4. 基于數(shù)組切片創(chuàng)建數(shù)組切片

類似于數(shù)組切片可以基于一個(gè)數(shù)組創(chuàng)建,數(shù)組切片也可以基于另一個(gè)數(shù)組切片創(chuàng)建。下面的例子基于一個(gè)已有數(shù)組切片創(chuàng)建新數(shù)組切片:

oldSlice := []int{1, 2, 3, 4, 5} 
newSlice := oldSlice[:3] // 基于oldSlice的前3個(gè)元素構(gòu)建新數(shù)組切片

有意思的是,選擇的oldSlicef元素范圍甚至可以超過所包含的元素個(gè)數(shù),比如newSlice可以基于oldSlice的前6個(gè)元素創(chuàng)建,雖然oldSlice只包含5個(gè)元素。只要這個(gè)選擇的范圍不超過oldSlice存儲(chǔ)能力(即cap()返回的值),那么這個(gè)創(chuàng)建程序就是合法的。newSlice中超出oldSlice元素的部分都會(huì)填上0。

5. 內(nèi)容復(fù)制

數(shù)組切片支持Go語言的另一個(gè)內(nèi)置函數(shù)copy(),用于將內(nèi)容從一個(gè)數(shù)組切片復(fù)制到另一個(gè)數(shù)組切片。如果加入的兩個(gè)數(shù)組切片不一樣大,就會(huì)按其中較小的那個(gè)數(shù)組切片的元素個(gè)數(shù)進(jìn)行復(fù)制。下面的示例展示了copy()函數(shù)的行為:

slice1 := []int{1, 2, 3, 4, 5} 
slice2 := []int{5, 4, 3} 
copy(slice2, slice1) // 只會(huì)復(fù)制slice1的前3個(gè)元素到slice2中
copy(slice1, slice2) // 只會(huì)復(fù)制slice2的3個(gè)元素到slice1的前3個(gè)位置

map

在C++/Java中,map一般都以庫的方式提供,比如在C++中是STL的std::map<>,在C#中是Dictionary<>,在Java中是Hashmap<>,在這些語言中,如果要使用map,事先要引用相應(yīng)的庫。而在Go中,使用map不需要引入任何庫,并且用起來也更加方便。

map是一堆鍵值對(duì)的未排序集合。比如以身份證號(hào)作為唯一鍵來標(biāo)識(shí)一個(gè)人的信息,則這個(gè)map可以定義為代碼清單 2-3所示的方式。

代碼清單2-3 map1.go

package main 
import "fmt" 
// PersonInfo是一個(gè)包含個(gè)人詳細(xì)信息的類型
type PersonInfo struct { 
 ID string
 Name string
 Address string
} 
func main() { 
var personDB map[string] PersonInfo 
 personDB = make(map[string] PersonInfo) 
 // 往這個(gè)map里插入幾條數(shù)據(jù)
 personDB["12345"] = PersonInfo{"12345", "Tom", "Room 203,..."} 
 personDB["1"] = PersonInfo{"1", "Jack", "Room 101,..."} 
 // 從這個(gè)map查找鍵為"1234"的信息
 person, ok := personDB["1234"]
 // ok是一個(gè)返回的bool型,返回true表示找到了對(duì)應(yīng)的數(shù)據(jù)
 if ok { 
 fmt.Println("Found person", person.Name, "with ID 1234.") 
 } else { 
 fmt.Println("Did not find person with ID 1234.") 
 } 
}

上面這個(gè)簡(jiǎn)單的例子基本上已經(jīng)覆蓋了map的主要用法,下面對(duì)其中的關(guān)鍵點(diǎn)進(jìn)行細(xì)述。

1. 變量聲明

map的聲明基本上沒有多余的元素,比如:

var myMap map[string] PersonInfo

其中,myMap是聲明的map變量名,string是鍵的類型,PersonInfo則是其中所存放的值類型。

2. 創(chuàng)建

我們可以使用Go語言內(nèi)置的函數(shù)make()來創(chuàng)建一個(gè)新map。下面的這個(gè)例子創(chuàng)建了一個(gè)鍵類型為string、值類型為PersonInfo的map:

myMap = make(map[string] PersonInfo)

也可以選擇是否在創(chuàng)建時(shí)指定該map的初始存儲(chǔ)能力,下面的例子創(chuàng)建了一個(gè)初始存儲(chǔ)能力為100的map:

myMap = make(map[string] PersonInfo, 100)

創(chuàng)建并初始化map的代碼如下:

myMap = map[string] PersonInfo{ 
 "1234": PersonInfo{"1", "Jack", "Room 101,..."}, 
}

3. 元素賦值

賦值過程非常簡(jiǎn)單明了,就是將鍵和值用下面的方式對(duì)應(yīng)起來即可:

myMap["1234"] = PersonInfo{"1", "Jack", "Room 101,..."}

4. 元素刪除

Go語言提供了一個(gè)內(nèi)置函數(shù)delete(),用于刪除容器內(nèi)的元素。下面我們簡(jiǎn)單介紹一下如何用delete()函數(shù)刪除map內(nèi)的元素:

delete(myMap, "1234")

上面的代碼將從myMap中刪除鍵為“1234”的鍵值對(duì)。如果“1234”這個(gè)鍵不存在,那么這個(gè)調(diào)用將什么都不發(fā)生,也不會(huì)有什么副作用。但是如果傳入的map變量的值是nil,該調(diào)用將導(dǎo)致程序拋出異常(panic)

5. 元素查找

在Go語言中,map的查找功能設(shè)計(jì)得比較精巧。而在其他語言中,我們要判斷能否獲取到一個(gè)值不是件容易的事情。判斷能否從map中獲取一個(gè)值的常規(guī)做法是:

(1) 聲明并初始化一個(gè)變量為空;

(2) 試圖從map中獲取相應(yīng)鍵的值到該變量中;

(3) 判斷該變量是否依舊為空,如果為空則表示map中沒有包含該變量。

這種用法比較啰唆,而且判斷變量是否為空這條語句并不能真正表意(是否成功取到對(duì)應(yīng)的值),從而影響代碼的可讀性和可維護(hù)性。有些庫甚至?xí)O(shè)計(jì)為因?yàn)橐粋€(gè)鍵不存在而拋出異常,讓開發(fā)者用起來膽戰(zhàn)心驚,不得不一層層嵌套try-catch語句,這更是不人性化的設(shè)計(jì)。在Go語言中,要從map中查找一個(gè)特定的鍵,可以通過下面的代碼來實(shí)現(xiàn):

value, ok := myMap["1234"] 
if ok { // 找到了
 // 處理找到的value 
}

判斷是否成功找到特定的鍵,不需要檢查取到的值是否為nil,只需查看第二個(gè)返回值ok,這讓表意清晰很多。配合:=操作符,讓你的代碼沒有多余成分,看起來非常清晰易懂。

到此,相信大家對(duì)“go語言有哪些類型及怎么表示”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

本文標(biāo)題:go語言有哪些類型及怎么表示
鏈接分享:http://chinadenli.net/article20/giosco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、App設(shè)計(jì)、網(wǎng)站內(nèi)鏈、標(biāo)簽優(yōu)化企業(yè)建站、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)