Golang中的* uint和uintptr有什么区别?

时间:2019-11-26 02:02:34

标签: pointers go

根据Golang tour,我们提供了以下整数类型:

Option Explicit
Public Sub WriteOutYesNos()
    Dim xmlDoc As Object, ws As Worksheet, results(), i As Long

    Set xmlDoc = CreateObject("MSXML2.DOMDocument")
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    results = Array("lotBatch", "serialNumber", "manufacturingDate")

    With xmlDoc
        .validateOnParse = True
        .setProperty "SelectionLanguage", "XPath"
        .setProperty "SelectionNamespaces", "xmlns:i='http://www.fda.gov/cdrh/gudid'"
        .async = False

        If Not .Load("https://accessgudid.nlm.nih.gov/devices/10806378034350.xml") Then
            Err.Raise .parseError.ErrorCode, , .parseError.reason
            Exit Sub
        End If
    End With

    With ws
        For i = LBound(results) To UBound(results)
            .Cells(i + 1, 1) = results(i)
            .Cells(i + 1, 2).Value = IIf(xmlDoc.SelectSingleNode("//i:" & results(i)).Text, "Yes", "No")
        Next
    End With
End Sub

从理论上讲,这意味着我们还可以如下指向所有这些类型的指针:

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

如果是这种情况,那么我们已经有一个指向* uint形式的uint的指针。这会使uintptr变得多余。 official documentation对此并没有太多启示:

*int  *int8  *int16  *int32  *int64
*uint *uint8 *uint16 *uint32 *uint64 *uintptr

据我了解,这意味着uint的位宽是在编译时根据目标体系结构(通常为32位或64位)确定的。指针宽度也应缩放到目标体系结构似乎是合乎逻辑的(IE:32位* uint指向32位uint)。 Golang是这种情况吗?

另一种想法是,也许添加了uintptr可以使语法在进行多个间接寻址时(IE:uintptr is an integer type that is large enough to hold the bit pattern of any pointer. foo *uinptr)更容易混淆?

我最后的想法是,在Golang中,指针和整数可能是不兼容的数据类型。这将非常令人沮丧,因为硬件本身在它们之间没有任何区别。例如,“分支到该地址”指令可以使用同一寄存器中与“添加此值”指令中使用的相同数据。

uintptr的真正意义(双关语)是什么?

3 个答案:

答案 0 :(得分:7)

简短的回答是“从不使用uintptr”。 ?

长答案是uintptr可以绕过类型系统,并允许Go实现者在Go中编写包括垃圾回收系统在内的Go运行时库,并调用包括系统调用的C调用代码使用根本无法通过 处理的C指针。

如果您是实施者(例如,提供对新操作系统上的系统调用的访问权限),则需要uintptr。您还需要知道使用它所需的所有特殊技巧,例如,如果OS要对OS级线程进行类似堆栈的操作,则将goroutine锁定到OS级线程。 (如果将它与Go指针一起使用,则可能还需要告诉编译器不要移动goroutine堆栈,这是通过特殊的编译时指令完成的。)

编辑:作为kostix notes in a comment,运行时系统将unsafe.Pointer视为对对象的引用,从而使该对象对GC保持活动状态。它uintptr视为此类参考。 (也就是说,unsafe.Pointer具有指针类型,uintptr具有整数类型。)另请参见documentation for the unsafe package

答案 1 :(得分:3)

您正在将uintptr和* uint混合使用。 uintptr在处理指针时使用,它是一种足以容纳指针的数据类型。它主要用于不安全的内存访问,请看不安全的程序包。 * uint是指向无符号整数的指针。

答案 2 :(得分:2)

uintptr只是内存地址的整数表示,无论它指向的是哪种实际类型。有点像C中的void *,或者只是将指针转换为整数。它的目的是用于不安全的黑魔法,而不是用于日常go代码中。