Package unsafe
…
The function
Offsetoftakes a (possibly parenthesized) selectors.f, denoting a fieldfof the struct denoted bysor*s, and returns the field offset in bytes relative to the struct’s address. Iffis an embedded field, it must be reachable without pointer indirections through fields of the struct. For a structswith fieldf:uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
I expect this is neither too confusing, nor too useful for most of us. But let’s use an example to make it glaringly obvious, just the same.
Let’s recall what we learned Wednesday about Sizeof, and apply it to a struct:
type X struct {
A int
B string
C float64
}
var x X
fmt.Println("X:"unsafe.Sizeof(x))
fmt.Println("X.A:", unsafe.Sizeof(x.A))
fmt.Println("X.B:", unsafe.Sizeof(x.B))
fmt.Println("xX.C:", unsafe.Sizeof(x.C))
On a 64-bit system, this little program should output:
X: 32
X.A: 8
X.B: 16
X.C: 8
So now, what are the offsets of x.A, x.B, and x.C? Simple arithmetic would suggest: 0, 0 + 8 (8), and 0 + 8 + 16 (24) respectively. Let’s see:
fmt.Println("X.A offset:", unsafe.Offsetof(x.A))
fmt.Println("X.B offset:", unsafe.Offsetof(x.B))
fmt.Println("X.C offset:", unsafe.Offsetof(x.C))
And indeed, we find the output is:
X.A offset: 0
X.B offset: 8
X.C offset: 24
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)