? ? ? ? ? ? ?大家好,這是我給大家準(zhǔn)備的新的一期專欄,專門講golang,從入門到精通各種框架和中間件,工具類庫,希望對go有興趣的同學(xué)可以訂閱此專欄。
---------------------------------------------------------------------------------------------------------------------------------
? ? ? ? ? ? ?上一篇文章中?【go從入門到精通】go包,內(nèi)置類型和初始化順序? 偏重概念和知識(shí),想必大家都對如何開始寫代碼已經(jīng)開始蠢蠢欲動(dòng)了,但是不要著急,基礎(chǔ)知識(shí)扎實(shí),能讓你少走很多彎道。
基本數(shù)據(jù)類型
? ? ? ? 正如前一篇的內(nèi)容,go的基本數(shù)據(jù)類型和其他語言都差不多,我們可以先看看go是如何聲明變量的。
標(biāo)準(zhǔn)聲明
Go語言的變量聲明格式為:
var 變量名 變量類型
變量聲明以關(guān)鍵字var
開頭,變量類型放在變量的后面,行尾無需分號(hào)。 舉個(gè)例子:
var str string
var i int32
var b bool
批量聲明
每聲明一個(gè)變量就需要寫var
關(guān)鍵字會(huì)比較繁瑣,go語言中還支持批量變量聲明:
var (
a string
b int
c bool
d float32
)
變量的初始化
Go語言在聲明變量的時(shí)候,會(huì)自動(dòng)對變量對應(yīng)的內(nèi)存區(qū)域進(jìn)行初始化操作。每個(gè)變量會(huì)被初始化成其類型的默認(rèn)值,例如: 整型和浮點(diǎn)型變量的默認(rèn)值為0。 字符串變量的默認(rèn)值為空字符串。 布爾型變量默認(rèn)為false
。 切片、函數(shù)、指針變量的默認(rèn)為nil
。
當(dāng)然我們也可在聲明變量的時(shí)候?yàn)槠渲付ǔ跏贾?。變量初始化的?biāo)準(zhǔn)格式如下:
var 變量名 類型 = 表達(dá)式
舉個(gè)例子:
? ? var a int32 = 1
?類型推導(dǎo)
有時(shí)候我們會(huì)將變量的類型省略,這個(gè)時(shí)候編譯器會(huì)根據(jù)等號(hào)右邊的值來推導(dǎo)變量的類型完成初始化。
? ? var str = "pprof.cn"
? ? var i = 1
短變量聲明
在函數(shù)內(nèi)部,可以使用更簡略的 := 方式聲明并初始化變量。
package main
import (
"fmt"
)
func main() {
var i = 10
j := 100
fmt.Println(i,j)
}
匿名變量
????????在使用多重賦值時(shí),如果想要忽略某個(gè)值,可以使用匿名變量。 匿名變量用一個(gè)下劃線_表示,例如我希望通過strconv。Atoi來將數(shù)字字符串轉(zhuǎn)整型數(shù)字,由于這個(gè)函數(shù)有2個(gè)返回值,我只想用i接收最終的整型變量,用_來作為匿名變量,可以用下面的代碼來實(shí)現(xiàn):
package main
import (
"fmt"
"strconv"
)
func main() {
i,_:=strconv.Atoi("100")
fmt.Println(i)
}
? ? ? ? ? ? 匿名變量不占用命名空間,不會(huì)分配內(nèi)存,所以匿名變量之間不存在重復(fù)聲明。 (在Lua等編程語言里,匿名變量也被叫做啞元變量。)
注意事項(xiàng):
? ? 函數(shù)外的每個(gè)語句都必須以關(guān)鍵字開始(var、const、func等)
? ? :=不能使用在函數(shù)外。
? ? _多用于占位,表示忽略值。
const常量的初始化
????????相對于變量,常量是恒定不變的值,多用于定義程序運(yùn)行期間不會(huì)改變的那些值。 常量的聲明和變量聲明非常類似,只是把var換成了const,常量在定義的時(shí)候必須賦值。
? ? const pi = 3.1415??
const同時(shí)聲明多個(gè)常量時(shí),如果省略了值則表示和上面一行的值相同。 例如:
? ? const (
? ? ? ? n1 = 100
? ? ? ? n2
? ? ? ? n3
? ? )
上面示例中,常量n1、n2、n3的值都是100。
其他注意的
但是這里要注意的一些區(qū)別是:
? ? ? (1) 空指針值 nil :
package main
import (
"fmt"
)
func main(){
i := 0
p := &i
if p == nil {
fmt.Println("p is nil")
}
}
? ? ? ?(2)多行字符串的輸出方式:
????????Go語言中要定義一個(gè)多行字符串時(shí),就必須使用反引號(hào)
字符:
package main
import (
"fmt"
)
func main(){
s := `this
is
golang
program`
fmt.Println(s)
}
反引號(hào)間換行將被作為字符串中的換行,但是所有的轉(zhuǎn)義字符均無效,文本將會(huì)原樣輸出。
? ??
? ? ? (3)byte和rune類型
????????組成每個(gè)字符串的元素叫做“字符”,可以通過遍歷或者單個(gè)獲取字符串元素獲得字符。 字符用單引號(hào)(’)包裹起來,如:
Go 語言的字符有以下兩種:
? ? uint8類型,或者叫 byte 型,代表了ASCII碼的一個(gè)字符。
? ? rune類型,代表一個(gè) UTF-8字符。
var a := '啊'
var b := 'b'
當(dāng)需要處理中文、日文或者其他復(fù)合字符時(shí),則需要用到rune
類型。rune
類型實(shí)際是一個(gè)int32
。
Go 使用了特殊的?rune
?類型來處理?Unicode
,讓基于?Unicode
的文本處理更為方便,也可以使用?byte
?型進(jìn)行默認(rèn)字符串處理,性能和擴(kuò)展性都有照顧
package main
import (
"fmt"
)
func disp() {
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)
}
}
func main() {
disp()
}
輸出:
104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 228(?) 189(?) 160( ) 229(?) 165(¥) 189(?)?
104(h) 101(e) 108(l) 108(l) 111(o) 32( ) 20320(你) 22909(好)
因?yàn)閁TF8編碼下一個(gè)中文漢字由3-4
個(gè)字節(jié)組成,所以我們不能簡單的按照字節(jié)去遍歷一個(gè)包含中文的字符串,否則就會(huì)出現(xiàn)上面輸出中第一行的結(jié)果。
字符串底層是一個(gè)byte數(shù)組,所以可以和[]byte類型相互轉(zhuǎn)換。字符串是不能修改的 字符串是由byte字節(jié)組成,所以字符串的長度是byte字節(jié)的長度。 rune類型用來表示utf8字符,一個(gè)rune字符由一個(gè)或多個(gè)byte組成。
我們有時(shí)候會(huì)有這樣的需求,判斷某個(gè)游戲玩家起的昵稱不能超過10個(gè)漢字或者字符,那么我想你這個(gè)時(shí)候就知道用哪種方式了。
?(4)修改字符串
????????要修改字符串,需要先將其轉(zhuǎn)換成[]rune或[]byte
,完成后再轉(zhuǎn)換為string
。無論哪種轉(zhuǎn)換,都會(huì)重新分配內(nèi)存,并復(fù)制字節(jié)數(shù)組。
package main
import (
"fmt"
)
func modstring1(s string) {
// 強(qiáng)制類型轉(zhuǎn)換
bytes := []byte(s)
bytes[0] = 'H'
fmt.Println(string(bytes))
}
func modstring2(s string) {
// 強(qiáng)制類型轉(zhuǎn)換
bytes := []rune(s)
bytes[0] = '你'
fmt.Println(string(bytes))
}
func main() {
s := "hello"
modstring1(s)
modstring2(s)
}
? ? ? (5)array數(shù)組? ??
? ? ? ? ? ? go的數(shù)組array是同一種數(shù)據(jù)類型的固定長度的序列。
? ? ? ? ?? (1)如何定義一個(gè)數(shù)組呢?我們可以用: var 數(shù)組名? ?[長度],不過你要注意的是長度也是數(shù)組類型的一部分。
? ? ? ? ? ? ?比如:
????????????????var a [10]int 和var a [100]int是不同的類型? ??
? ? ? ? ? ? ? ?var arr0 [5]int = [5]int{1, 2, 3}? // 未初始化元素值為 0。?
? ? ? ? ? ? ? ?c := [5]int{2: 100, 4: 200} // 使用索引號(hào)初始化元素。
? ? ? ? ? ? ? ?var arr2 = [...]int{1, 2, 3, 4, 5, 6}??// 通過初始化值確定數(shù)組長度。
? ? ? ? ??
? ? ? ? ? ? (2)數(shù)組可以通過下標(biāo)進(jìn)行訪問,下標(biāo)是從0開始,最后一個(gè)元素下標(biāo)是:len-1
? ? ? ? ? 遍歷數(shù)組有兩種方式:
? ? for i := 0; i < len(a); i++ {
? ? }
? ? for index, v := range a {
? ? }
? ? ? ? ? ? ?(3)訪問越界,如果下標(biāo)在數(shù)組合法范圍之外,則觸發(fā)訪問越界,會(huì)panic
? ? ? ? ?
package main
import "fmt"
func main() {
a := [3]int{1, 2, 3}
b := a[0]
c := a[6]
fmt.Println(b, c)
}
?運(yùn)行時(shí)報(bào)錯(cuò)信息如下:
PS E:\project\go\hello> ./main.exe
panic: runtime error: index out of range [6] with length 3
goroutine 1 [running]:
main.main()
E:/project/go/hello/main.go:8 +0x1d
? ? ? ? ?
? ? ? ?????????(4)?數(shù)組是值類型,賦值和傳參會(huì)復(fù)制整個(gè)數(shù)組,而不是指針。因此改變副本的值,不會(huì)改變本身的值。
? ? ? ?此時(shí)此刻,? ? 一定有人想做下驗(yàn)證,于是寫了如下代碼:
package main
import "fmt"
func fun1(a []int) {
a[0] = 100
}
func main() {
a := []int{1, 2, 3}
fun1(a)
fmt.Println(a[0])
}
? ? ? ?這段代碼似乎是想修改數(shù)組a的第一個(gè)元素的值,但是很不幸,你可能認(rèn)為調(diào)用fun1之后,a的第一個(gè)元素的值仍然是1。
? ? ? 為什么呢?? 因?yàn)槟銈鞯牟皇菙?shù)組,而且切片。 數(shù)組是指定了長度,且是值傳遞 而切片是沒有指定長度,且是引用傳遞。所以你的代碼改成這樣就沒有問題了:
package main
import "fmt"
func fun1(a [3]int) {
a[0] = 100
}
func main() {
a := [3]int{1, 2, 3}
fun1(a)
fmt.Println(a[0])
}
? ?(6)slice和map
? ? ? ?后邊逐步針對這slIce,map,以及和數(shù)組的三者之間的比較差異來細(xì)細(xì)道來。?
類型轉(zhuǎn)換
????????Go語言中只有強(qiáng)制類型轉(zhuǎn)換,沒有隱式類型轉(zhuǎn)換。該語法只能在兩個(gè)類型之間支持相互轉(zhuǎn)換的時(shí)候使用。
強(qiáng)制類型轉(zhuǎn)換的基本語法如下:
? ? ? ? 目標(biāo)類型(表達(dá)式)
其中,目標(biāo)類型表示要轉(zhuǎn)換的類型。表達(dá)式包括變量、復(fù)雜算子和函數(shù)返回值等.
package main
import (
"fmt"
)
func main() {
i := int32(0)
var j int
j = i
fmt.Println(j)
}
?比如這段代碼,簡簡單單,但是編譯的時(shí)候報(bào)錯(cuò):
cannot use i (variable of type int32) as int value in assignment
所以我們在把i賦值給j的時(shí)候,需要做個(gè)類型強(qiáng)制轉(zhuǎn)換,j = int(i)
運(yùn)算符
? ? ? ? ?go的常用的運(yùn)算符用法和其他語言沒有區(qū)別文章來源:http://www.zghlxwxcb.cn/news/detail-837324.html
? ? ??文章來源地址http://www.zghlxwxcb.cn/news/detail-837324.html
到了這里,關(guān)于【go從入門到精通】go基本類型和運(yùn)算符用法的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!