多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 另一个 usafe 包的例子 在这一节,你会了解到更多关于 unsafe 库的东西,以及通过一个 moreUnsafe.go 的小程序来了解 unsafe 库的兼容性。moreUnsafe.go 做的事情就是使用指针来访问数组里的所有元素。 ```Go package main import ( "fmt" "unsafe" ) func main() { array := [...]int{0, 1, -2, 3, 4} pointer := &array[0] fmt.Print(*pointer, " ") memoryAddress := uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) for i := 0; i < len(array)-1; i++ { pointer = (*int)(unsafe.Pointer(memoryAddress)) fmt.Print(*pointer, " ") memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) } ``` 首先,`pointer`变量指向`array[0]`的地址,`array[0]`是整型数组的第一个元素。接下来指向整数值的`pointer`变量会传入`unsafe.Pointer()`方法,然后传入`uintptr`。最后结果存到了`memoryAddress`里。 `unsafe.Sizeof(array[0])`的值使你可以进入数组的下一个元素,因为这是每个数组元素占用的内存。因此,该值将在 for 循环的每次迭代中添加到`memoryAddress`变量中,从而使你可以获取下一个数组元素的内存地址。 `*pointer`表示法取消引用指针并返回存储的整数值。 第三部分代码: ```Go fmt.Println() pointer = (*int)(unsafe.Pointer(memoryAddress)) fmt.Print("One more: ", *pointer, " ") memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) fmt.Println() ``` 在最后一部分中,我们尝试使用指针和内存地址访问数组中不存在的元素。由于使用了`unsafe`包,Go 编译器无法捕获此类逻辑错误,因此将返回不正确的内容。 执行`moreUnsafe.go`将会输出: ```shell $ go run moreUnsafe.go 0 1 -2 3 4 One more: 824634208008 ``` 你刚刚使用指针访问了 Go 数组的所有元素。但是,这里的真正问题是,当你尝试访问无效的数组元素时,程序没有抛出错误,而是返回了一个随机数。