Go 經(jīng)典入門(mén)系列 4:類型
這是我們 Golang 系列教程的第 4 個(gè)教程。
請(qǐng)閱讀本系列的 Golang 教程第 3 部分:變量來(lái)學(xué)習(xí)變量的知識(shí)。
下面是 Go 支持的基本類型:
bool 數(shù)字類型 int8, int16, int32, int64, int uint8, uint16, uint32, uint64, uint float32, float64 complex64, complex128 byte rune string
bool
bool 類型表示一個(gè)布爾值,值為 true 或者 false。
package?main
import?"fmt"
func?main()?{
????a?:=?true
????b?:=?false
????fmt.Println("a:",?a,?"b:",?b)
????c?:=?a?&&?b
????fmt.Println("c:",?c)
????d?:=?a?||?b
????fmt.Println("d:",?d)
}
在線運(yùn)行程序[1]
在上面的程序中,a 賦值為 true,b 賦值為 false。
c 賦值為 a && b。僅當(dāng) a 和 b 都為 true 時(shí),操作符 && 才返回 true。因此,在這里 c 為 false。
當(dāng) a 或者 b 為 true 時(shí),操作符 || 返回 true。在這里,由于 a 為 true,因此 d 也為 true。我們將得到程序的輸出如下。
a:?true?b:?false
c:?false
d:?true
有符號(hào)整型
int8:表示 8 位有符號(hào)整型大小:8 位范圍:-128~127
int16:表示 16 位有符號(hào)整型大小:16 位范圍:-32768~32767
int32:表示 32 位有符號(hào)整型大小:32 位范圍:-2147483648~2147483647
int64:表示 64 位有符號(hào)整型大小:64 位范圍:-9223372036854775808~9223372036854775807
int:根據(jù)不同的底層平臺(tái)(Underlying Platform),表示 32 或 64 位整型。除非對(duì)整型的大小有特定的需求,否則你通常應(yīng)該使用 int 表示整型。大小:在 32 位系統(tǒng)下是 32 位,而在 64 位系統(tǒng)下是 64 位。范圍:在 32 位系統(tǒng)下是 -2147483648~2147483647,而在 64 位系統(tǒng)是 -9223372036854775808~9223372036854775807。
package?main
import?"fmt"
func?main()?{
????var?a?int?=?89
????b?:=?95
????fmt.Println("value?of?a?is",?a,?"and?b?is",?b)
}
在線運(yùn)行程序[2]
上面程序會(huì)輸出 value of a is 89 and b is 95。
在上述程序中,a 是 int 類型,而 b 的類型通過(guò)賦值(95)推斷得出。上面我們提到,int 類型的大小在 32 位系統(tǒng)下是 32 位,而在 64 位系統(tǒng)下是 64 位。接下來(lái)我們會(huì)證實(shí)這種說(shuō)法。
在 Printf 方法中,使用 %T 格式說(shuō)明符(Format Specifier),可以打印出變量的類型。Go 的 unsafe[3] 包提供了一個(gè) Sizeof[4] 函數(shù),該函數(shù)接收變量并返回它的字節(jié)大小。unsafe 包應(yīng)該小心使用,因?yàn)槭褂?unsafe 包可能會(huì)帶來(lái)可移植性問(wèn)題。不過(guò)出于本教程的目的,我們是可以使用的。
下面程序會(huì)輸出變量 a 和 b 的類型和大小。格式說(shuō)明符 %T 用于打印類型,而 %d 用于打印字節(jié)大小。
package?main
import?(
????"fmt"
????"unsafe"
)
func?main()?{
????var?a?int?=?89
????b?:=?95
????fmt.Println("value?of?a?is",?a,?"and?b?is",?b)
????fmt.Printf("type?of?a?is?%T,?size?of?a?is?%d",?a,?unsafe.Sizeof(a))?//?a?的類型和大小
????fmt.Printf("\ntype?of?b?is?%T,?size?of?b?is?%d",?b,?unsafe.Sizeof(b))?//?b?的類型和大小
}
在線運(yùn)行程序[5]
以上程序會(huì)輸出:
value?of?a?is?89?and?b?is?95
type?of?a?is?int,?size?of?a?is?4
type?of?b?is?int,?size?of?b?is?4
從上面的輸出,我們可以推斷出 a 和 b 為 int 類型,且大小都是 32 位(4 字節(jié))。如果你在 64 位系統(tǒng)上運(yùn)行上面的代碼,會(huì)有不同的輸出。在 64 位系統(tǒng)下,a 和 b 會(huì)占用 64 位(8 字節(jié))的大小。
無(wú)符號(hào)整型
uint8:表示 8 位無(wú)符號(hào)整型大小:8 位范圍:0~255
uint16:表示 16 位無(wú)符號(hào)整型大小:16 位范圍:0~65535
uint32:表示 32 位無(wú)符號(hào)整型大小:32 位范圍:0~4294967295
uint64:表示 64 位無(wú)符號(hào)整型大小:64 位范圍:0~18446744073709551615
uint:根據(jù)不同的底層平臺(tái),表示 32 或 64 位無(wú)符號(hào)整型。大小:在 32 位系統(tǒng)下是 32 位,而在 64 位系統(tǒng)下是 64 位。范圍:在 32 位系統(tǒng)下是 0~4294967295,而在 64 位系統(tǒng)是 0~18446744073709551615。
浮點(diǎn)型
float32:32 位浮點(diǎn)數(shù)float64:64 位浮點(diǎn)數(shù)
下面一個(gè)簡(jiǎn)單程序演示了整型和浮點(diǎn)型的運(yùn)用。
package?main
import?(
????"fmt"
)
func?main()?{
????a,?b?:=?5.67,?8.97
????fmt.Printf("type?of?a?%T?b?%T\n",?a,?b)
????sum?:=?a?+?b
????diff?:=?a?-?b
????fmt.Println("sum",?sum,?"diff",?diff)
????no1,?no2?:=?56,?89
????fmt.Println("sum",?no1+no2,?"diff",?no1-no2)
}
在線運(yùn)行程序[6]
a 和 b 的類型根據(jù)賦值推斷得出。在這里,a 和 b 的類型為 float64(float64 是浮點(diǎn)數(shù)的默認(rèn)類型)。我們把 a 和 b 的和賦值給變量 sum,把 b 和 a 的差賦值給 diff,接下來(lái)打印 sum 和 diff。no1 和 no2 也進(jìn)行了相同的計(jì)算。上述程序?qū)?huì)輸出:
type?of?a?float64?b?float64
sum?14.64?diff?-3.3000000000000007
sum?145?diff?-33
復(fù)數(shù)類型
complex64:實(shí)部和虛部都是 float32 類型的的復(fù)數(shù)。complex128:實(shí)部和虛部都是 float64 類型的的復(fù)數(shù)。
內(nèi)建函數(shù) **complex**[7] 用于創(chuàng)建一個(gè)包含實(shí)部和虛部的復(fù)數(shù)。complex 函數(shù)的定義如下:
func?complex(r,?i?FloatType)?ComplexType
該函數(shù)的參數(shù)分別是實(shí)部和虛部,并返回一個(gè)復(fù)數(shù)類型。實(shí)部和虛部應(yīng)該是相同類型,也就是 float32 或 float64。如果實(shí)部和虛部都是 float32 類型,則函數(shù)會(huì)返回一個(gè) complex64 類型的復(fù)數(shù)。如果實(shí)部和虛部都是 float64 類型,則函數(shù)會(huì)返回一個(gè) complex128 類型的復(fù)數(shù)。
還可以使用簡(jiǎn)短語(yǔ)法來(lái)創(chuàng)建復(fù)數(shù):
c?:=?6?+?7i
下面我們編寫(xiě)一個(gè)簡(jiǎn)單的程序來(lái)理解復(fù)數(shù)。
package?main
import?(
????"fmt"
)
func?main()?{
????c1?:=?complex(5,?7)
????c2?:=?8?+?27i
????cadd?:=?c1?+?c2
????fmt.Println("sum:",?cadd)
????cmul?:=?c1?*?c2
????fmt.Println("product:",?cmul)
}
在線運(yùn)行程序[8]
在上面的程序里,c1 和 c2 是兩個(gè)復(fù)數(shù)。c1的實(shí)部為 5,虛部為 7。c2 的實(shí)部為8,虛部為 27。c1 和 c2 的和賦值給 cadd ,而 c1 和 c2 的乘積賦值給 cmul。該程序?qū)⑤敵觯?/p>
sum:?(13+34i)
product:?(-149+191i)
其他數(shù)字類型
byte 是 uint8 的別名。rune 是 int32 的別名。
在學(xué)習(xí)字符串的時(shí)候,我們會(huì)詳細(xì)討論 byte 和 rune。
string 類型
在 Golang 中,字符串是字節(jié)的集合。如果你現(xiàn)在還不理解這個(gè)定義,也沒(méi)有關(guān)系。我們可以暫且認(rèn)為一個(gè)字符串就是由很多字符組成的。我們后面會(huì)在一個(gè)教程中深入學(xué)習(xí)字符串。
下面編寫(xiě)一個(gè)使用字符串的程序。
package?main
import?(
????"fmt"
)
func?main()?{
????first?:=?"Naveen"
????last?:=?"Ramanathan"
????name?:=?first?+"?"+?last
????fmt.Println("My?name?is",name)
}
在線運(yùn)行程序[9]
上面程序中,first 賦值為字符串 "Naveen",last 賦值為字符串 "Ramanathan"。+ 操作符可以用于拼接字符串。我們拼接了 first、空格和 last,并將其賦值給 name。上述程序?qū)⒋蛴≥敵?My name is Naveen Ramanathan。
還有許多應(yīng)用于字符串上面的操作,我們將會(huì)在一個(gè)單獨(dú)的教程里看見(jiàn)它們。
類型轉(zhuǎn)換
Go 有著非常嚴(yán)格的強(qiáng)類型特征。Go 沒(méi)有自動(dòng)類型提升或類型轉(zhuǎn)換。我們通過(guò)一個(gè)例子說(shuō)明這意味著什么。
package?main
import?(
????"fmt"
)
func?main()?{
????i?:=?55??????//int
????j?:=?67.8????//float64
????sum?:=?i?+?j?//不允許?int?+?float64
????fmt.Println(sum)
}
在線運(yùn)行程序[10]
上面的代碼在 C 語(yǔ)言中是完全合法的,然而在 Go 中,卻是行不通的。i 的類型是 int ,而 j 的類型是 float64 ,我們正試圖把兩個(gè)不同類型的數(shù)相加,Go 不允許這樣的操作。如果運(yùn)行程序,你會(huì)得到 main.go:10: invalid operation: i + j (mismatched types int and float64)。
要修復(fù)這個(gè)錯(cuò)誤,i 和 j 應(yīng)該是相同的類型。在這里,我們把 j 轉(zhuǎn)換為 int 類型。把 v 轉(zhuǎn)換為 T 類型的語(yǔ)法是 T(v)。
package?main
import?(
????"fmt"
)
func?main()?{
????i?:=?55??????//int
????j?:=?67.8????//float64
????sum?:=?i?+?int(j)?//j?is?converted?to?int
????fmt.Println(sum)
}
在線運(yùn)行程序[11]
現(xiàn)在,當(dāng)你運(yùn)行上面的程序時(shí),會(huì)看見(jiàn)輸出 122。
賦值的情況也是如此。把一個(gè)變量賦值給另一個(gè)不同類型的變量,需要顯式的類型轉(zhuǎn)換。下面程序說(shuō)明了這一點(diǎn)。
package?main
import?(
????"fmt"
)
func?main()?{
????i?:=?10
????var?j?float64?=?float64(i)?//?若沒(méi)有顯式轉(zhuǎn)換,該語(yǔ)句會(huì)報(bào)錯(cuò)
????fmt.Println("j",?j)
}
在線運(yùn)行程序[12]
在第 9 行,i 轉(zhuǎn)換為 float64 類型,接下來(lái)賦值給 j。如果不進(jìn)行類型轉(zhuǎn)換,當(dāng)你試圖把 i 賦值給 j 時(shí),編譯器會(huì)拋出錯(cuò)誤。
本教程到此為止。請(qǐng)?jiān)谠u(píng)論區(qū)留下您的反饋和疑問(wèn)。
下一教程 - 常量[13]
via: https://golangbot.com/types/
作者:Nick Coghlan[14]譯者:Noluye[15]校對(duì):polaris1119[16]
本文由 GCTT[17] 原創(chuàng)編譯,Go 中文網(wǎng)[18] 榮譽(yù)推出
參考資料
在線運(yùn)行程序: https://play.golang.org/p/v_W3HQ0MdY
[2]在線運(yùn)行程序: https://play.golang.org/p/NyDPsjkma3
[3]unsafe: https://golang.org/pkg/unsafe/
[4]Sizeof: https://golang.org/pkg/unsafe/#Sizeof
[5]在線運(yùn)行程序: https://play.golang.org/p/mFsmjVk5oc
[6]在線運(yùn)行程序: https://play.golang.org/p/upwUCprT-j
[7]complex: https://golang.org/pkg/builtin/#complex
[8]在線運(yùn)行程序: https://play.golang.org/p/kEz1uKCdKs
[9]在線運(yùn)行程序: https://play.golang.org/p/CI6phwSVel
[10]在線運(yùn)行程序: https://play.golang.org/p/m-TMRpmmnm
[11]在線運(yùn)行程序: https://play.golang.org/p/mweu3n3jMy
[12]在線運(yùn)行程序: https://play.golang.org/p/Y2uSYYr46c
[13]常量: https://studygolang.com/articles/11872
[14]Nick Coghlan: https://golangbot.com/about/
[15]Noluye: https://github.com/Noluye
[16]polaris1119: https://github.com/polaris1119
[17]GCTT: https://github.com/studygolang/GCTT
[18]Go 中文網(wǎng): https://studygolang.com/
推薦閱讀
