<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 1923字,需瀏覽 4分鐘

           ·

          2020-07-16 00:14

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

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

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

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

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

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

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

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

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


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

          作者:ChrisSiebenmann[3]譯者:dust347[4]校對(duì):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]

          這個(gè)有教育意義的 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 語(yǔ)言,掃碼回復(fù)「進(jìn)群」即可


          站長(zhǎng) polarisxu

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

          不限于 Go 技術(shù)

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


          Go語(yǔ)言中文網(wǎng)

          每天為你

          分享 Go 知識(shí)

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




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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大鸡巴成人性爱在线视频 | 欧美久久草 | 日本黄色电影大鸡巴 | 国产黄视频在线免费看 | 神马久久樱桃 |