1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        為什么 Go 關(guān)心 unsafe.Pointer 和 uintptr 之間的差別

        共 1923字,需瀏覽 4分鐘

         ·

        2020-07-16 00:14

        點(diǎn)擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注我們,領(lǐng)全套Go資料,每天學(xué)習(xí)?Go?語言

        Go 有兩樣?xùn)|西或多或少是無類型指針的表示:uintptr 和 unsafe.Pointer (和外表相反,它們是內(nèi)置類型)。從表面上看這有點(diǎn)奇怪,因?yàn)?unsafe.Pointer 和 uintptr 可以彼此來回轉(zhuǎn)換。為什么不只有一種指針表現(xiàn)形式?兩者之間有什么區(qū)別?

        表面的區(qū)別是可以對 uintptr 進(jìn)行算數(shù)運(yùn)算但不能對 unsafe.Pointer(或任何其他 Go 指針)進(jìn)行運(yùn)算。unsafe 包的文檔指出了重要的區(qū)別:

        uintptr 是整數(shù),不是引用。將 Pointer 轉(zhuǎn)換為 uintptr 會創(chuàng)建一個沒有指針語義的整數(shù)值。即使 uintptr 持有某個對象的地址,如果對象移動,垃圾收集器并不會更新 uintptr 的值,uintptr 也無法阻止該對象被回收。

        盡管 unsafe.Pointer 是通用指針,但 Go 垃圾收集器知道它們指向 Go 對象;換句話說,它們是真正的 Go 指針。通過內(nèi)部魔法,垃圾收集器可以并且將使用它們來防止活動對象被回收并發(fā)現(xiàn)更多活動對象(如果unsafe.Pointer指向的對象自身持有指針)。因此,對 unsafe.Pointer 的合法操作上的許多限制歸結(jié)為“在任何時候,它們都必須指向真正的 Go 對象”。如果創(chuàng)建的 unsafe.Pointer 并不符合,即使很短的時間,Go 垃圾收集器也可能會在該時刻掃描,然后由于發(fā)現(xiàn)了無效的 Go 指針而崩潰。

        相比之下,uintptr 只是一個數(shù)字。這種特殊的垃圾收集魔法機(jī)制并不適用于 uintptr 所“引用”的對象,因?yàn)樗鼉H僅是一個數(shù)字,一個 uintptr 不會引用任何東西。反過來,這導(dǎo)致在將 unsafe.Pointer 轉(zhuǎn)換為 uintptr,對其進(jìn)行操作然后再將其轉(zhuǎn)回的各種方式上存在許多微妙的限制?;疽笫且赃@種方式進(jìn)行操作,使編譯器和運(yùn)行時可以屏蔽不安全的指針的臨時非指針性,使其免受垃圾收集器的干擾,因此這種臨時轉(zhuǎn)換對于垃圾收集將是原子的。

        (我想,我在文章將內(nèi)存塊復(fù)制到 Go 結(jié)構(gòu)中[1]里對 unsafe.Pointer 的使用是安全的,但我承認(rèn)我現(xiàn)在不確定。我相信 cgo 會有一些不可思議的機(jī)制,因?yàn)樗梢园踩刂圃斐霾话踩闹羔槪@些指針指向 C 內(nèi)存而不是 Go 內(nèi)存。)

        PS:從 Go 1.8 開始,即使當(dāng)時沒有運(yùn)行垃圾回收,所有 Go 指針必須始終有效(我相信也包括 unsafe.Pointer)。如果您在變量或字段中存儲了無效的指針,則僅通過將字段更新為包括 nil 在內(nèi)的完全有效的值即可使代碼崩潰。例如,請參閱這個有教育意義的 Go bug report[2]。

        (我本想嘗試講一下內(nèi)部魔法,它允許垃圾收集器處理未類型化的 unsafe.Pointer 指針,但我認(rèn)為對其了解不足,甚至無法說出它使用的是哪種魔法。)


        via: https://utcc.utoronto.ca/~cks/space/blog/programming/GoUintptrVsUnsafePointer

        作者:ChrisSiebenmann[3]譯者:dust347[4]校對:polaris1119[5]

        本文由 GCTT[6] 原創(chuàng)編譯,Go 中文網(wǎng)[7] 榮譽(yù)推出

        參考資料

        [1]

        將內(nèi)存塊復(fù)制到 Go 結(jié)構(gòu)中: https://utcc.utoronto.ca/~cks/space/blog/programming/GoMemoryToStructures

        [2]

        這個有教育意義的 Go bug report: https://github.com/golang/go/issues/19135

        [3]

        ChrisSiebenmann: https://utcc.utoronto.ca/~cks/space/People/ChrisSiebenmann

        [4]

        dust347: https://github.com/dust347

        [5]

        polaris1119: https://github.com/polaris1119

        [6]

        GCTT: https://github.com/studygolang/GCTT

        [7]

        Go 中文網(wǎng): https://studygolang.com/



        推薦閱讀


        學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進(jìn)群」即可


        站長 polarisxu

        自己的原創(chuàng)文章

        不限于 Go 技術(shù)

        職場和創(chuàng)業(yè)經(jīng)驗(yàn)


        Go語言中文網(wǎng)

        每天為你

        分享 Go 知識

        Go愛好者值得關(guān)注




        瀏覽 48
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            新婚之夜初次的呻吟嗯 | 国产精品成人AV电影 | 看中国一级片日逼的 | 我在开会他在下添好爽在 | 人人操操| www.vkvta.com | 一级特黄AAAAAA级大仟 | 男女24式动态图 | 国产精品久久久久久久久免费相片 | 男女无遮挡毛片免费视频色大師 |