go 变量和类型
一个变量就是一块内存(有的变量不占内存空间),
变量的类型规定了你 如何从这块内存里读取数据和写入数据,且给这个类型的变量一些”操作方法”,比如 数组的下标操作
1 大小端
2 代码判断大小端
3 变量类型与类型转换
变量的类型规定了你如何从这块内存里读取数据和写入数据
类型的转换无非就是你换了一种读写数据的方式而已
func main() {
// 1000 0011
var a uint8 = 131
println(a)
// 变成有符号的, 那么它的数据的读取方式就变了
// 1000 0011 负数的补码
// 反码 1000 0010
// 原码 1111 1101 = -125
b := int8(a)
println(b) // -125
}3.1 一块可读写的内存,是不是可以按照我任意的方式来读写呢?
是的, 你想怎么读写,就怎么读写
package main
import (
"unsafe"
)
type FF struct {
i int32
j int8
k int8
}
func main() {
// 我们这里假定 z和 a 变量之间是连续的 (因为可能不一定是连续的!)
var z int32 = 1800
var a, b, c, d int8 = 2, 4, 3, 1
ptr := unsafe.Pointer(&d)
// 格式化(类型转换) 理解为 你想这么去读写这块内存上的数据
// 这里当然你可以就用 (*int32)(ptr) 来格式化 读取4个字节的测试
ff := (*FF)(ptr)
//0xc00004c753 0xc00004c752 0xc00004c751 0xc00004c750
println(&a, &b, &c, &d)
// 0xc00004c754
println(&z)
// 0xc00004c750 0xc00004c754
println(&ff.i, &ff.j)
// 33817345 8 7
println(ff.i, ff.j, ff.k)
// 直接修改了z 原来那块内存上某个字节上的数据了.
// 当然如果要去改变量的某个字节上的数据, 可以用位运算..
ff.j = 9
// 1801
println(z)
ff.k = 1
// 265
println(z)
}- 再举个例子
package main
import (
"unsafe"
)
type dd struct {
i1 int8
arr [3]int8
}
func main() {
d := 33817345
// 想怎么格式化就怎么格式化
// 想怎么读写数据就怎么格式化它
d2 := (*dd)(unsafe.Pointer(&d))
println(d2.i1, d2.arr[0], d2.arr[1], d2.arr[2])
d2.arr[0] = 6
println(d)
}理解了类型,使用起 (unsafe.Pointer) 会变得更容易
4 指针的类型
Tip
- 指针: 它的值是一个地址, 一般说它指向一个内存地址
- 指针类型: 说明了你用什么样的方式结构去读取它指向的那块内存