亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

go強(qiáng)制類型轉(zhuǎn)換type(a)以及范圍引起的數(shù)據(jù)差異

 更新時(shí)間:2023年10月09日 14:14:26   作者:海生  
這篇文章主要為大家介紹了go強(qiáng)制類型轉(zhuǎn)換type(a)以及范圍引起的數(shù)據(jù)差異,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、介紹

golang中的類型轉(zhuǎn)換分強(qiáng)制類型轉(zhuǎn)換類型斷言普通變量類型int,float,string 都可以使用type(a)這種形式來進(jìn)行強(qiáng)制類型轉(zhuǎn)換

二、數(shù)字的類型轉(zhuǎn)換int和float

1、整數(shù)類型 int

func TestInt(t *testing.T) {
    var i int = -1
    var i8 int8 = int8(i)
    var i16 int16 = int16(i)
    var i32 int32 = int32(i)
    var i64 int64 = int64(i)
    t.Log(i, i8, i16, i32, i64) //-1 -1 -1 -1 -1
    var n int = 1111111
    var n8 int8 = int8(n)
    var n16 int16 = int16(n)
    var n32 int32 = int32(n)
    var n64 int64 = int64(n)
    t.Log(n, n8, n16, n32, n64) //1111111 71 -3001 1111111 1111111
}

我們發(fā)現(xiàn)當(dāng) 在轉(zhuǎn)換n的過程中,轉(zhuǎn)成int8和int16的時(shí)候,出現(xiàn)了錯(cuò)誤,為什么會這樣?

在于int類型在mac上是默認(rèn)的64個(gè)bit,

int8 表示 -128 到 127 之間的整數(shù)值 (8個(gè)bit)

int16 表示 -32768 和 32767 之間的整數(shù)值 (16個(gè)bit)

他們之間能夠存儲的范圍是不相同的,如果超過了某個(gè)類型的范圍就會出錯(cuò)。

2、正整數(shù)類型 uint

func TestUint(t *testing.T) {
    var i uint = 1
    var i8 uint8 = uint8(i)
    var i16 uint16 = uint16(i)
    var i32 uint32 = uint32(i)
    var i64 uint64 = uint64(i)
    t.Log(i, i8, i16, i32, i64) //1 1 1 1 1
    var u uint = 1111111
    var u8 uint8 = uint8(u)
    var u16 uint16 = uint16(u)
    var u32 uint32 = uint32(u)
    var u64 uint64 = uint64(u)
    t.Log(u, u8, u16, u32, u64) //1111111 71 62535 1111111 1111111
}

在類型范圍內(nèi)的數(shù)據(jù)轉(zhuǎn)換正確,范圍外的轉(zhuǎn)換錯(cuò)誤。

3、int和uint之間的強(qiáng)制轉(zhuǎn)換

func TestInt2(t *testing.T) {
    var i int = -1
    var i8 uint8 = uint8(i)
    var i16 uint16 = uint16(i)
    var i32 uint32 = uint32(i)
    var i64 uint64 = uint64(i)
    t.Log(i, i8, i16, i32, i64) //-1 255 65535 4294967295 18446744073709551615
    var n int = 1
    var n8 uint8 = uint8(n)
    var n16 uint16 = uint16(n)
    var n32 uint32 = uint32(n)
    var n64 uint64 = uint64(n)
    t.Log(n, n8, n16, n32, n64) //1 1 1 1 1
    var u int = 1111111
    var u8 uint8 = uint8(u)
    var u16 uint16 = uint16(u)
    var u32 uint32 = uint32(u)
    var u64 uint64 = uint64(u)
    t.Log(u, u8, u16, u32, u64) //1111111 71 62535 1111111 1111111
}

我們發(fā)現(xiàn)當(dāng)每種類型范圍不一樣的話,轉(zhuǎn)換不留神還是會有很大的錯(cuò)誤。

4、float32和float64的強(qiáng)制轉(zhuǎn)換

func TestFloat(t *testing.T) {
    var f32 float32 = 333.333
    var f64 float64 = float64(f32)
    t.Log(f32, f64) //333.333 333.3330078125

    //都在各自的范圍內(nèi)
    var fl64 float64 = 333.333
    var fl32 float32 = float32(fl64)
    t.Log(fl64, fl32) //333.333 333.333

    //大類型的范圍 超過小的類型范圍
    var flo64 float64 = 33333333333333333.333
    var flo32 float32 = float32(flo64)
    t.Log(flo64, flo32) //333.333 333.333
}

首先我們判斷float32和float64有什么不同,因?yàn)槭褂脙?nèi)存大小不一樣,導(dǎo)致精度以及范圍的不同。

  • float32和float64互相轉(zhuǎn)化,因?yàn)榫炔灰粯?,?dǎo)致數(shù)據(jù)差異
  • float32和float64互相轉(zhuǎn)化,因?yàn)榉秶灰粯樱瑢?dǎo)致數(shù)據(jù)差異

5、float和int互相轉(zhuǎn)換

func TestFloatInt(t *testing.T) {
    var i int = 333
    var f32 float32 = float32(i)
    var f64 float64 = float64(i)
    t.Log(i, f32, f64) //333 333 333
    var f float32 = 333.3
    var n int = int(f)
    var n8 int8 = int8(f)
    var n16 int16 = int16(f)
    var n32 int32 = int32(f)
    var n64 int64 = int64(f)
    t.Log(f, n, n8, n16, n32, n64) //333.3 333 77 333 333 333
}

因?yàn)槭莔ac系統(tǒng),我這里int是有符號64位整數(shù)數(shù)據(jù)類型。

類型比特?cái)?shù)有效數(shù)字數(shù)值范圍
int6464-2^63 ( -9,223,372,036,854,775,808)2^63-1(+9,223,372,036,854,775,807 )
float32326-7-3.410(-38)~3.410(38)
float646415-16-1.710(-308)~1.710(308)

基本上當(dāng)int轉(zhuǎn)成float類型只要在范圍內(nèi)的就沒有啥問題
而float轉(zhuǎn)成int的時(shí)候,需要考慮,小數(shù)點(diǎn)后面的會自動的舍去,以及范圍問題。

三、指針unsafe.Pointer任意類型與具體指針類型的轉(zhuǎn)換

注意,指針unsafe.Pointer任意類型,只能轉(zhuǎn)成 具體類型的指針類型
如轉(zhuǎn)成int類型的指針類型 *int
強(qiáng)制準(zhǔn)換的語法為 type(a),那么就是這里(*int)(a),而不是int(a)!

1、指針unsafe.Pointer轉(zhuǎn)成int指針類型

func TestIntPointer(t *testing.T) {
    //范圍內(nèi)可以正確轉(zhuǎn)化的情況
    var i int = 100
    pi := unsafe.Pointer(&i)
    //轉(zhuǎn)成int相關(guān)類型
    var n *int = (*int)(pi)
    var n8 *int8 = (*int8)(pi)
    var n16 *int16 = (*int16)(pi)
    var n32 *int32 = (*int32)(pi)
    var n64 *int64 = (*int64)(pi)
    t.Log(*n, *n8, *n16, *n32, *n64)//100 100 100 100 100
    //--------------------------
    //范圍超出的情況
    var i2 int = 10000
    pi2 := unsafe.Pointer(&i2)
    //轉(zhuǎn)成int相關(guān)類型
    var nn *int = (*int)(pi2)
    var nn8 *int8 = (*int8)(pi2)
    var nn16 *int16 = (*int16)(pi2)
    var nn32 *int32 = (*int32)(pi2)
    var nn64 *int64 = (*int64)(pi2)
    t.Log(*nn, *nn8, *nn16, *nn32, *nn64)//10000 16 10000 10000 10000
}

這里雖然是指針了,但還是需要注意具體類型的范圍。

不然超出類型的最大或者最小值,仍然是錯(cuò)誤的。

2、指針unsafe.Pointer轉(zhuǎn)成struct指針類型

還是type(a)的方式,這里的a變量為 unsafe.Pointer(&a)
type為 (*Struct)

完整的表達(dá)式為 (*Struct)(unsafe.Pointer(&a))

func TestStruct(t *testing.T) {
    //有一個(gè)struct結(jié)構(gòu)體S,里面width和height兩個(gè)int類型
    type S struct {
        wight  int
        height int
    }
    s := S{
        wight:  5,
        height: 6,
    }
    p := unsafe.Pointer(&s) //{5 6}
    t.Log(s)
    //測試轉(zhuǎn)成為T,T里面有w和h兩個(gè)int類型
    type T struct {
        w int
        h int
    }
    st := (*T)(p)
    t.Log(*st) //{5 6}
}

發(fā)現(xiàn)雖然S和T兩個(gè)結(jié)構(gòu)體不一樣,但卻轉(zhuǎn)成了正確的值,為什么?

因?yàn)橹羔橁P(guān)注的內(nèi)存控股,不管是S里的wight或者T里面的w,其實(shí)都是int類型,占用了相同的內(nèi)存

所以能夠正確的解析出來

如果此時(shí)我們把 T的類型改一下成int8試試,就會發(fā)現(xiàn)錯(cuò)誤

func TestStruct(t *testing.T) {
    //有一個(gè)struct結(jié)構(gòu)體S,里面width和height兩個(gè)int類型
    type S struct {
        wight  int
        height int
    }
    s := S{
        wight:  5,
        height: 6,
    }
    p := unsafe.Pointer(&s) //{5 6}
    t.Log(s)
    //測試轉(zhuǎn)成為T,T里面有w和h兩個(gè)int8類型
    type T struct {
        w int8
        h int8
    }
    st := (*T)(p)
    t.Log(*st) //{5 0}
}

第一個(gè)獲取的5值,是因?yàn)樵谥羔樀?偏移量所以能夠獲取到,也正好在范圍內(nèi),如果S.wight=10000
那么第一個(gè)也會錯(cuò)誤,如下

func TestStruct(t *testing.T) {
    //有一個(gè)struct結(jié)構(gòu)體S,里面width和height兩個(gè)int類型
    type S struct {
        wight  int
        height int
    }
    s := S{
        wight:  10000,
        height: 6,
    }
    p := unsafe.Pointer(&s) //{10000 6}
    t.Log(s)
    //測試轉(zhuǎn)成為T,T里面有w和h兩個(gè)int8類型
    type T struct {
        w int8
        h int8
    }
    st := (*T)(p)
    t.Log(*st) //{16 39}
}

所以我們可以得出如果是指針類型的話,只要里面的指針是一樣的,才能強(qiáng)制轉(zhuǎn)換成正確的值。

以上就是go強(qiáng)制類型轉(zhuǎn)換type(a)以及范圍引起的數(shù)據(jù)差異的詳細(xì)內(nèi)容,更多關(guān)于go強(qiáng)制類型轉(zhuǎn)換type數(shù)據(jù)差異的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang中的同步工具sync.WaitGroup詳解

    Golang中的同步工具sync.WaitGroup詳解

    這篇文章主要詳細(xì)為大家介紹了Golang中的同步工具sync.WaitGroup,文中有詳細(xì)的代碼示例,具有很好的參考價(jià)值,希望對大家有所幫助,一起跟隨小編過來看看吧
    2023-05-05
  • Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn)

    Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn)

    RSA 是最常用的非對稱加密算法,本文主要介紹了Golang RSA生成密鑰、加密、解密、簽名與驗(yàn)簽的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 深入分析Go?實(shí)現(xiàn)?MySQL?數(shù)據(jù)庫事務(wù)

    深入分析Go?實(shí)現(xiàn)?MySQL?數(shù)據(jù)庫事務(wù)

    本文深入分析了Go語言實(shí)現(xiàn)MySQL數(shù)據(jù)庫事務(wù)的原理和實(shí)現(xiàn)方式,包括事務(wù)的ACID特性、事務(wù)的隔離級別、事務(wù)的實(shí)現(xiàn)方式等。同時(shí),本文還介紹了Go語言中的事務(wù)處理機(jī)制和相關(guān)的API函數(shù),以及如何使用Go語言實(shí)現(xiàn)MySQL數(shù)據(jù)庫事務(wù)。
    2023-06-06
  • golang接口的正確用法分享

    golang接口的正確用法分享

    這篇文章主要介紹了golang接口的正確用法分享的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • Go語言帶緩沖的通道的使用

    Go語言帶緩沖的通道的使用

    Go語言中有緩沖的通道是一種在被接收前能存儲一個(gè)或者多個(gè)值的通道,本文就來介紹一下Go語言帶緩沖的通道的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • 解讀golang中的const常量和iota

    解讀golang中的const常量和iota

    這篇文章主要介紹了golang中的const常量和iota,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 深入理解Golang中指針的用途與技巧

    深入理解Golang中指針的用途與技巧

    在 Go 語言中,指針是一種重要的概念,了解和正確使用指非常關(guān)鍵,因此本文小編就來和大家講講Golang 中指針的概念與用法,希望對大家有所幫助
    2023-05-05
  • Go內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧

    Go內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧

    這篇文章主要為大家詳細(xì)介紹了Go語言內(nèi)存分配之結(jié)構(gòu)體優(yōu)化技巧的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • go語言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)

    go語言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)

    set集合是一種常見的數(shù)據(jù)結(jié)構(gòu),它代表了一個(gè)唯一元素的集合,本文主要介紹了set的基本特性,包括唯一性、無序性、可變性和集合運(yùn)算,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 一文詳解Go語言io.LimitedReader類型

    一文詳解Go語言io.LimitedReader類型

    這篇文章主要為大家介紹了Go語言io.LimitedReader類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評論