根据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的真正意义(双关语)是什么?
答案 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代码中。