日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go 学习笔记(4)— Go 标识符、数据类型之间转换、布尔型、整型、浮点型、interface 类型

發布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go 学习笔记(4)— Go 标识符、数据类型之间转换、布尔型、整型、浮点型、interface 类型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 標識符整體分類

Go 標識符整體分類如下圖所示:

2. 數據類型分類

Go 語言按類別有以下幾種數據類型:

類型描述
布爾型布爾型的值只可以是常量 true 或者 false
數字類型整型 int 和浮點型 float32、float64,Go語言支持整型和浮點型數字,并且支持復數,其中位的運算采用補碼
字符串類型字符串就是一串固定長度的字符連接起來的字符序列。 Go 語言的字符串的字節使用 UTF-8 編碼標識 Unicode 文本
派生類型(a) 指針類型(Pointer)
(b) 數組類型
? 結構化類型(struct)
(d) Channel 類型
(e) 函數類型
(f) 切片類型
(g) 接口類型(interface)
(h) Map 類型

注意:

  1. 布爾類型數據和整型數據不能直接進行轉換;
var a bool = true
a = 10 // cannot use 10 (type int) as type bool in assignment
a := 100
if a {// Error: non-bool a (type int) used as if conditionprintln("true")
}
  1. Go 語言不存在隱式類型轉換,因此所有的類型轉換都必須顯式的聲明,不同類型的不能直接轉化,必須強制類型轉換;

轉換方式:

valueOfTypeB = typeB(valueOfTypeA)
a := 5.0
b := int(a)
package mainfunc main() {var a int = 10var b int32 = 10b = a	// cannot use a (type int) as type int32 in assignmentif a == b { // invalid operation: a == b (mismatched types int and int32)println("a is equal b ")}
}
  1. 對于整數類型值、整數常量之間的類型轉換,原則上只要源值在目標類型的可表示范圍內就是合法的。

Go 語言使用類型前置加括號的方式進行類型轉換 , 一般格式如下 :

T(表達式)

其中, T 代表要轉換的類型。表達式包括變量、復雜算子和函數返回值等。類型轉換 時 ,需要考慮兩種類型的關系和范圍,是否會發生數值截斷等。

比如,之所以 uint8(255) 可以把無類型的常量 255 轉換為 uint8 類型的值,是因為 255 在 [0, 255] 的范圍內。但需要特別注意的是,源整數類型的可表示范圍較大,而目標類型的可表示范圍較小的情況,比如把值的類型從 int16 轉換為 int8 。請看下面這段代碼:

	var srcInt = int16(-255)dstInt := int8(srcInt)fmt.Println(dstInt)	// 1

一定要記住,當整數值的類型的有效范圍由寬變窄時,只需在補碼形式下截掉一定數量的高位二進制數即可。

類似的快刀斬亂麻規則還有:當把一個浮點數類型的值轉換為整數類型值時,前者的小數部分會被全部截掉

  1. 雖然直接把一個整數值轉換為一個 string 類型的值是可行的,但值得關注的是,被轉換的整數值應該可以代表一個有效的 Unicode 代碼點,否則轉換的結果將會是"�"(僅由高亮的問號組成的字符串值)。

字符’�’的 Unicode 代碼點是U+FFFD。它是 Unicode 標準中定義的 Replacement Character,專用于替換那些未知的、不被認可的以及無法展示的字符。

string(-1)	// "�"

總結:

package mainimport ("fmt"
)func main() {// 重點1的示例。var srcInt = int16(-255)// 請注意,之所以要執行uint16(srcInt),是因為只有這樣才能得到全二進制的表示。// 例如,fmt.Printf("%b", srcInt)將打印出"-11111111",后者是負數符號再加上srcInt的絕對值的補碼。// 而fmt.Printf("%b", uint16(srcInt))才會打印出srcInt原值的補碼"1111111100000001"。fmt.Printf("The complement of srcInt: %b (%b)\n", uint16(srcInt), srcInt)// The complement of srcInt: 1111111100000001 (-11111111)dstInt := int8(srcInt)fmt.Printf("The complement of dstInt: %b (%b)\n", uint8(dstInt), dstInt)// The complement of dstInt: 1 (1)fmt.Printf("The value of dstInt: %d\n", dstInt)//	The value of dstInt: 1fmt.Println()// 重點2的示例。fmt.Printf("The Replacement Character: %s\n", string(-1))// The Replacement Character: �fmt.Printf("The Unicode codepoint of Replacement Character: %U\n", '�')// The Unicode codepoint of Replacement Character: U+FFFDfmt.Println()
}

2.1 數字類型詳細劃分

類型描述
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)

盡管在某些特定的運行環境下 intuintuintptr 的大小可能相等,但是它們依然是不同的類型,比如 intint32 ,雖然 int 類型的大小也可能是 32 bit,但是在需要把 int 類型當做 int32 類型使用的時候必須顯示的對類型進行轉換,反之亦然。

Golang 中,整數類型長度與操作系統有關,32 位系統中,整數類型長度是 4 個字節,在 64 位系統中,整數類型長度是 8 個字節。

Go 語言中有符號整數采用 2 的補碼形式表示,也就是最高 bit 位用來表示符號位,一個 n-bit 的有符號數的取值范圍是從 -2 到 2-1。

無符號整數的所有 bit 位都用于表示非負數,取值范圍是 0 到 2。例如,int8 類型整數的取值范圍是從 -128 到 127,而 uint8 類型整數的取值范圍是從 0 到 255。

哪些情況下使用 intuint ?

程序邏輯對整型范圍沒有特殊需求。例如,對象的長度使用內建 len() 函數返回,這個長度可以根據不同平臺的字節長度進行變化。實際使用中,切片或 map 的元素數量等都可以用 int 來表示。

事實上,內置的 len 函數返回一個有符號的 int ,我們可以像下面例子那樣處理逆序循環。

medals := []string{"gold", "silver", "bronze"}
for i := len(medals) - 1; i >= 0; i-- {fmt.Println(medals[i]) // "bronze", "silver", "gold"
}

如果 len 函數返回一個無符號數,那么 i 也將是無符號的 uint 類型,然后條件i >= 0則永遠為真。在三次迭代之后,也就是i == 0時, i-- 語句將不會產生 -1,而是變成一個 uint 類型的最大值(可能是2^64-1),然后 medals[i] 表達式運行時將發生 panic 異常,也就是試圖訪問一個 slice 范圍以外的元素。

反之,在二進制傳輸、讀寫文件的結構描述、位運算、哈希和加密操作等時,為了保持文件的結構不會受到不同編譯目標平臺字節長度的影響,通常使用 uint

Unicode 字符 rune 類型是和 int32 等價的類型,通常用于表示一個 Unicode 碼點。這兩個名稱可以互換使用。同樣 byte 也是 uint8 類型的等價類型, byte 類型一般用于強調數值是一個原始的數據而不是一個小的整數。

一個算術運算的結果,不管是有符號或者是無符號的,如果需要更多的 bit 位才能正確表示的話,就說明計算結果是溢出了。超出的高位的 bit 位部分將被丟棄。如果原始的數值是有符號類型,而且最左邊的 bit 位是1的話,那么最終結果可能是負的,例如 int8 的例子:

var u uint8 = 255
fmt.Println(u, u+1, u*u) // "255 0 1"
var i int8 = 127
fmt.Println(i, i+1, i*i) // "127 -128 1"

2.2 浮點類型詳細劃分

類型描述
float32IEEE-754 32位浮點型數
float64IEEE-754 64位浮點型數
complex6432 位實數和虛數
complex12864 位實數和虛數
  • float32 的浮點數的最大范圍約為 3.4e38, 可以使用常量定義: math.MaxFloat32

  • float64 的浮點數的最大范圍約為 1.8e308,可以使用常量定義: math.MaxFloat64

  • float32 類型的浮點數可以提供大約 6 個十進制數的精度,

  • float64 則可以提供約 15 個十進制數的精度;

通常應該優先使用 float64 類型,因為 float32 類型的累計計算誤差很容易擴散,并且 float32 能精確表示的正整數并不是很大(譯注:因為 float32 的有效 bit 位只有23個,其它的 bit 位用于指數和符號;當整數大于 23 bit 能表達的范圍時, float32 的表示將出現誤差):

var f float32 = 16777216 // 1 << 24
fmt.Println(f == f+1)    // "true"!

Printf 函數的 %g 參數打印浮點數,將采用更緊湊的表示形式打印,并提供足夠的精度,但是對應表格的數據,使用 %e (帶指數)或 %f 來控制保留幾位小數的形式打印可能更合適。所有的這三個打印形式都可以指定打印的寬度和控制打印精度。

for x := 0; x < 8; x++ {fmt.Printf("x = %d e^x = %8.3f\n", x, math.Exp(float64(x)))
}

如果只保留小數部分的精度,則使用 %.3f 表示保留 3 位小數的精度。

上面代碼打印 e 的冪,打印精度是小數點后三個小數精度和 8 個字符寬度:

x = 0       e^x =    1.000
x = 1       e^x =    2.718
x = 2       e^x =    7.389
x = 3       e^x =   20.086
x = 4       e^x =   54.598
x = 5       e^x =  148.413
x = 6       e^x =  403.429
x = 7       e^x = 1096.633

Go語言提供了兩種精度的復數類型: complex64complex128 ,分別對應 float32float64 兩種浮點數精度。內置的 complex 函數用于構建復數,內建的 realimag 函數分別返回復數的實部和虛部:

var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y)                 // "(-5+10i)"
fmt.Println(real(x*y))           // "-5"
fmt.Println(imag(x*y))           // "10"

如果一個浮點數面值或一個十進制整數面值后面跟著一個 i ,例如 3.141592i或 2i,它將構成一個復數的虛部,復數的實部是 0:

fmt.Println(1i * 1i) // "(-1+0i)", i^2 = -1

在常量算術規則下,一個復數常量可以加到另一個普通數值常量(整數或浮點數、實部或虛部),我們可以用自然的方式書寫復數,就像 1+2i 或與之等價的寫法 2i+1 。上面 x 和 y 的聲明語句還可以簡化:

x := 1 + 2i
y := 3 + 4i

復數也可以用 ==!= 進行相等比較。只有兩個復數的實部和虛部都相等的時候它們才是相等的(譯注:浮點數的相等比較是危險的,需要特別小心處理精度問題)。

參考:Go 語言圣經

2.3 其它數字類型劃分

類型描述
byte等同 uint8
rune等同 int32
uint32 或 64 位
int與 uint 一樣大小
uintptr無符號整型,用于存放一個指針

Go 語言內建的基本類型中就存在兩個別名類型。byteuint8 的別名類型,而 runeint32 的別名類型。

3. interface 類型

由于 Go 語言中任何對象實例都滿足空接口 interface{} ,所以 interface{} 看起來像是可以指向任何對象的 Any 類型,如下:

var v1 interface{} = 1 // 將int類型賦值給interface{}
var v2 interface{} = "abc" // 將string類型賦值給interface{}
var v3 interface{} = &v2 // 將*interface{}類型賦值給interface{}
var v4 interface{} = struct{ X int }{1}
var v5 interface{} = &struct{ X int }{1}

當函數可以接受任意的對象實例時,我們會將其聲明為 interface{} ,最典型的例子是標準庫 fmtPrintXXX 系列的函數,例如:

func Printf(fmt string, args ...interface{})
func Println(args ...interface{})

Go 語言中,interface{} 代表空接口,任何類型都是它的實現類型。任何類型的值都可以很方便地被轉換成空接口的值就行了,這里的具體語法是 interface{}(x)

你可能會對這里的 {} 產生疑惑,為什么在關鍵字 interface 的右邊還要加上這個東西?請記住,一對不包裹任何東西的花括號,除了可以代表空的代碼塊之外,還可以用于表示不包含任何內容的數據結構(或者說數據類型)。

而空接口 interface{} 則代表了不包含任何方法定義的、空的接口類型。當然了,對于一些集合類的數據類型來說,{} 還可以用來表示其值不包含任何元素,比如空的切片值 []string{} ,以及空的字典值 map[int]string{}

總結

以上是生活随笔為你收集整理的Go 学习笔记(4)— Go 标识符、数据类型之间转换、布尔型、整型、浮点型、interface 类型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。