網(wǎng)站首頁 編程語言 正文
整數(shù)
按位長度分度分為:8位,16位,32位,64位。
對應(yīng)有符號整數(shù):int8,int16,int32,int64。
對應(yīng)無符號整數(shù):uint8,uint16,uint32,uint64。
計算最大數(shù)和最小數(shù)規(guī)則:
- 有符號整數(shù):由于有符號,因此位數(shù)的最高位被用來存儲符號,其他為存儲數(shù)據(jù)值,所以對于
n
位數(shù)來說,取值范圍是:-2^(n-1)^~2^(n-1)^-1,對應(yīng)int8來說,就是 -127 ~ 127。 - 無符號正數(shù):不需要用最高位記錄符號,全部位數(shù)表示數(shù)字。取值范圍是:0 ~ 2^n^-1。對于int8來說,就是0 ~ 255。
特殊的整數(shù)類型
int
和uint
以及uintptr
。
int
和uint
根據(jù)特定的平臺,其大小與原生的整數(shù)相同或者是該平臺上運算效率最高的值。要么同時是64位,要么同時是32位,但也不能假定他們就是64位或者32位的整型。即使在一樣的硬件下,不同編譯器也有可能選用不同的大小。
至于uintptr
,它的大小并不明確。但它肯定足夠容納一個指針的大小。常用于底層編程。
雖然int
、uint
的長度可能與int32
、int64
、..
其他整型相同但是他們是不同的類型。
如果想確定int
和uint
的大小
fmt.Println(runtime.GOARCH) // 看看CPU型號 fmt.Println(strconv.IntSize) // 這才是int的大小,上面只是提供一個對照
溢出
不論是有符號數(shù)還是無符號數(shù),若計算結(jié)果所需的位超出類型的范圍,就稱為溢出。溢出的高位會被無提示地拋棄。
var i int8 = -128 fmt.Println(i-1) // 127 var i2 int8 = 127 fmt.Println(i2+1) // -128 var u uint8 = 0 fmt.Println(u-1) // 255 var u2 uint8 = 255 fmt.Println(u2+1) // 0
浮點數(shù)
float32
、float64
。遵循IEEE 754
標(biāo)準(zhǔn)。
math.MaxFloat32
給出了float32
類型的最大值:3.4028234663852886e+38
。
math.MaxFloat64
則是float64
類型的最大值:1.7976931348623157e+308
。
浮點數(shù)可以用來表示小數(shù)。
十進制下,float32
有效位大約是6位。float64
有效位大約是15位。
浮點數(shù)的打印可以使用:
-
%g
,保留足夠的精度顯示 -
%e
,使用指數(shù)形式顯示 -
%f
,使用無指數(shù)形式顯示
f := 2.71828 fmt.Printf("%g, %[1]e, %[1]f \n", f) // 2.71828, 2.718280e+00, 2.718280
復(fù)數(shù)
complex64
、complex128
?,二者分別由float32
和float64
組成。
使用real
函數(shù)提取復(fù)數(shù)的實部,使用imag
函數(shù)提取復(fù)數(shù)的虛部。
浮點數(shù)或者整數(shù)后面加i
就會變成一個虛數(shù),且它的實部為0
。
x := 1+2i y := 3+4i
布爾值
bool
類型就是布爾值,有true
(真)和false
(假)兩個值。
布爾值無法隱式轉(zhuǎn)換成數(shù)值,數(shù)值也不能轉(zhuǎn)成布爾值。
它的零值是false
。
一元操作符!
表示邏輯取反。!true
表示false
。
字符串
string
表示字符串。它是不可變的字節(jié)序列。Go中的字符串內(nèi)部實現(xiàn)用UTF-8
編碼。
字符串的“長度”與遍歷字符串的做法
字符串的“長度”
對字符串調(diào)用len
函數(shù),獲取到的不是字符串的長度(字符的個數(shù)),而是字符串的字節(jié)數(shù)(字節(jié)切片的長度)。
如下,盡管字符個數(shù)只有6,但字節(jié)長度len(s)
卻有18,這是因為中文字符以UTF-8
存儲,通常包含3~4個字節(jié)。
s := "中文字節(jié)數(shù)多" fmt.Println("len: ", len(s)) // len: 18
對字符串使用下標(biāo)索引操作,會返回對應(yīng)索引的字節(jié),而不是字符。
s := "中文字節(jié)數(shù)多" fmt.Println("len: ", len(s)) // len: 18 for i :=0; i < len(s); i++ { fmt.Printf("%d, %[1]c, %[1]T\n",s[i]) }
對應(yīng)的輸出如下:
len: 18
228, ?, uint8
184, ?, uint8
173, -, uint8
230, ?, uint8
150, ?, uint8
135, ?, uint8
229, ?, uint8
173, -, uint8
151, ?, uint8
232, è, uint8
138, ?, uint8
130, ?, uint8
230, ?, uint8
149, ?, uint8
176, °, uint8
229, ?, uint8
164, ¤, uint8
154, ?, uint8
因此不要隨便亂用字符串的下標(biāo)操作,否則可能獲得有意想不到的結(jié)果。
遍歷字符串
由上面的下標(biāo)操作可以看出,對字符串的下標(biāo)索引操作會獲得單個字節(jié)而不是字符,假如現(xiàn)在我們想處理的是UTF-8
解碼的字符的話,有兩種方式,基本思路都是處理成rune
類型:
第一種,用UTF-8
解碼器顯式處理這些字符,unicode/utf8
包示例。
utf8.RuneCountInString(s)
返回字符串轉(zhuǎn)為rune
后的個數(shù),Go使用rune
代表一個UTF-8
字符。
utf8.utf8.DecodeRuneInString(s[i:])
處理當(dāng)前字符串,并算出下一個rune
以及它所占的字節(jié)數(shù)。
s := "What? 中文字節(jié)數(shù)多" runeCount := utf8.RuneCountInString(s) fmt.Println("runeCount:", runeCount) // runeCount: 12 for i:= 0; i<len(s); { r, size:= utf8.DecodeRuneInString(s[i:]) fmt.Printf("i: %d, r:%q, type:%T \n", i, r, r) i += size }
輸出如下:
runeCount: 12
i: 0, r:'W', type:int32
i: 1, r:'h', type:int32
i: 2, r:'a', type:int32
i: 3, r:'t', type:int32
i: 4, r:'?', type:int32
i: 5, r:' ', type:int32
i: 6, r:'中', type:int32
i: 9, r:'文', type:int32
i: 12, r:'字', type:int32
i: 15, r:'節(jié)', type:int32
i: 18, r:'數(shù)', type:int32
i: 21, r:'多', type:int32
第二種,用range
循環(huán),Go會隱式的進行UTF-8
解碼。
注意,這里的i
,指的是字節(jié)的下標(biāo),而不是字符的下標(biāo)。
s := "What? 中文字節(jié)數(shù)多" for i, r := range s { fmt.Printf("i: %d, rune: %q, type: %T \n", i, r, r) }
輸出如下:
i: 0, rune: 'W', type: int32
i: 1, rune: 'h', type: int32
i: 2, rune: 'a', type: int32
i: 3, rune: 't', type: int32
i: 4, rune: '?', type: int32
i: 5, rune: ' ', type: int32
i: 6, rune: '中', type: int32
i: 9, rune: '文', type: int32
i: 12, rune: '字', type: int32
i: 15, rune: '節(jié)', type: int32
i: 18, rune: '數(shù)', type: int32
i: 21, rune: '多', type: int32
Rune與Byte(字節(jié))
int32
的別名是rune
,天然適合存儲單個文字符號,為Go所采用的。
rune
類型值代表一個UTF-8
字符。以字節(jié)(byte)為單位對Unicode
碼點作變長編碼。現(xiàn)在計算機都用UTF-8
來表示單個字符。
字符串的是由“字符”組成的,字符用單引號’
包裹起來,如:
var b = 'h' c := '沖' fmt.Printf("%d, %q \n", b, b) // 104, 'h' fmt.Printf("%d, %q \n", c, c) // 20914, '沖'
字節(jié),byte
類型,底層類型是uint8
,由8個bit
組成,它可以代表一個ASCII
碼。ASCII
碼是滿足早期計算機的使用的,它用7位表示128個“字符”(ASCII字符):大小寫英文字母、數(shù)字、標(biāo)點符號和設(shè)備控制符。
字符串與字節(jié)slice的轉(zhuǎn)換
字符串底層是一個字節(jié)數(shù)組,所以可以和[]byte
類型互換。
s := "abc" b := []byte(s) s2 := string(b)
概念上,[]byte(s)
轉(zhuǎn)換操作會分配新的字節(jié)數(shù)組,拷貝填入s
含有的字節(jié),并生成一個slice
的引用,指向整個數(shù)組。反之,用string(b)
也會產(chǎn)生一份副本而不是操作真正的b
,以此保證上面s2
不變。
字符串不可變
字符串是不可變的,表現(xiàn)在其字符串值不可修改。平時我們看到的字符串修改操作、拼接操作并不改變原有的字符串值,而是將操作后生成新的字符串值賦予原來的變量。
s := "left foot" t := s s += ", right foot"
盡管字符串創(chuàng)建后,它底層的字節(jié)slice不可變,但是普通的字節(jié)slice
是可以隨意改變的。
var a = []byte{'h', 'e', 'l', 'l', 'o'} fmt.Printf("%p, %[1]q \n", a) // 0xc00000a098, "hello" a[4] = ' ' fmt.Printf("%p, %[1]q \n", a) // 0xc00000a098, "hell "
由于字符串的不可變以及避免頻繁的操作字符串而導(dǎo)致的多次內(nèi)存分配和復(fù)制,可以使用bytes.Buffer
類型。
見GOPL的一個例子:
func intsToString(values []int) string { var buf bytes.Buffer buf.WriteByte('[') for i, v := range values { if i > 0 { buf.WriteString(",") } fmt.Fprintf(&buf, "%d", v) } buf.WriteByte(']') return buf.String() } func main() { fmt.Println(intsToString([]int{1, 2, 3})) // [1,2,3] }
追加ASCII
字符可以用writeByte
,追加UTF-8
編碼的文字符號,最好用WriteRune
方法。
基本類型的值都是可比較的
基本類型的值都是可比較的,如布爾值、數(shù)值、字符串等。
數(shù)值的類型轉(zhuǎn)換
很多整型—整型的轉(zhuǎn)換不會引起值的變化,僅告知編譯器如何解讀這么值。但縮減大小的類型轉(zhuǎn)換,以及整型與浮點型的相互轉(zhuǎn)換,會因此值的改變或者損失精度。
浮點型轉(zhuǎn)整型會舍棄小數(shù)部分并向0取整。
var f = 3.526 i := int(f) fmt.Printf("f: %v, i: %v \n", f, i) // f: 3.526, i: 3 var i16 = int16(555) var i8 = int8(i16) fmt.Printf("i16: %v, i8: %v \n", i16, i8) // i16: 555, i8: 43
運算符
運算符降序排列:
* / % << >> & &^ + - | ^ == != < <= > >= && ||
二元運算符分為五大優(yōu)先級。同級別的運算符滿足左結(jié)合律,可以用圓括號指定次序。
常量
常量是一種表達(dá)式,保證在編譯階段就計算出對應(yīng)的值。所有常量本質(zhì)上都屬于基本類型:布爾型、字符串或者數(shù)字。
常量自編譯后,其值恒定不變。
type Integer int const I Integer = 10 const S string = "important_secret" const ( NUM1 = 1 NUM2 = 2 NUM3 NUM4 = 5.5 STR1 = "STR1" ) func main() { fmt.Printf("I: %v \n", I) fmt.Printf("S: %v \n", S) fmt.Printf("NUM1: %v \n", NUM1) fmt.Printf("NUM2: %v \n", NUM2) fmt.Printf("NUM3: %v \n", NUM3) fmt.Printf("NUM4: %v \n", NUM4) fmt.Printf("STR1: %v \n", STR1) }
輸出如下:
I: 10
S: important_secret
NUM1: 1
NUM2: 2
NUM3: 2
NUM4: 5.5
STR1: STR1
原文鏈接:https://juejin.cn/post/7120939408051994638
相關(guān)推薦
- 2022-07-07 python如何實現(xiàn)數(shù)組元素兩兩相加_python
- 2022-03-28 c語言for、while和do-while循環(huán)之間的區(qū)別_C 語言
- 2022-05-03 使用EF的Code?First模式操作數(shù)據(jù)庫_實用技巧
- 2022-06-10 使用Android實現(xiàn)一個懸浮在軟鍵盤上的輸入欄_Android
- 2022-05-14 解決Linux未啟用網(wǎng)卡的問題_Linux
- 2022-03-31 C#值類型、引用類型、泛型、集合、調(diào)用函數(shù)的表達(dá)式樹實踐_C#教程
- 2022-07-26 Fatal error in launcher: Unable to create process
- 2022-05-25 創(chuàng)建指定大小文件,怎么創(chuàng)建?
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支