亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

directory search
archive archive/tar archive/zip bufio bufio(緩存) builtin builtin(內(nèi)置包) bytes bytes(包字節(jié)) compress compress/bzip2(壓縮/bzip2) compress/flate(壓縮/flate) compress/gzip(壓縮/gzip) compress/lzw(壓縮/lzw) compress/zlib(壓縮/zlib) container container/heap(容器數(shù)據(jù)結(jié)構(gòu)heap) container/list(容器數(shù)據(jù)結(jié)構(gòu)list) container/ring(容器數(shù)據(jù)結(jié)構(gòu)ring) context context(上下文) crypto crypto(加密) crypto/aes(加密/aes) crypto/cipher(加密/cipher) crypto/des(加密/des) crypto/dsa(加密/dsa) crypto/ecdsa(加密/ecdsa) crypto/elliptic(加密/elliptic) crypto/hmac(加密/hmac) crypto/md5(加密/md5) crypto/rand(加密/rand) crypto/rc4(加密/rc4) crypto/rsa(加密/rsa) crypto/sha1(加密/sha1) crypto/sha256(加密/sha256) crypto/sha512(加密/sha512) crypto/subtle(加密/subtle) crypto/tls(加密/tls) crypto/x509(加密/x509) crypto/x509/pkix(加密/x509/pkix) database database/sql(數(shù)據(jù)庫/sql) database/sql/driver(數(shù)據(jù)庫/sql/driver) debug debug/dwarf(調(diào)試/dwarf) debug/elf(調(diào)試/elf) debug/gosym(調(diào)試/gosym) debug/macho(調(diào)試/macho) debug/pe(調(diào)試/pe) debug/plan9obj(調(diào)試/plan9obj) encoding encoding(編碼) encoding/ascii85(編碼/ascii85) encoding/asn1(編碼/asn1) encoding/base32(編碼/base32) encoding/base64(編碼/base64) encoding/binary(編碼/binary) encoding/csv(編碼/csv) encoding/gob(編碼/gob) encoding/hex(編碼/hex) encoding/json(編碼/json) encoding/pem(編碼/pem) encoding/xml(編碼/xml) errors errors(錯誤) expvar expvar flag flag(命令行參數(shù)解析flag包) fmt fmt go go/ast(抽象語法樹) go/build go/constant(常量) go/doc(文檔) go/format(格式) go/importer go/parser go/printer go/scanner(掃描儀) go/token(令牌) go/types(類型) hash hash(散列) hash/adler32 hash/crc32 hash/crc64 hash/fnv html html html/template(模板) image image(圖像) image/color(顏色) image/color/palette(調(diào)色板) image/draw(繪圖) image/gif image/jpeg image/png index index/suffixarray io io io/ioutil log log log/syslog(日志系統(tǒng)) math math math/big math/big math/bits math/bits math/cmplx math/cmplx math/rand math/rand mime mime mime/multipart(多部分) mime/quotedprintable net net net/http net/http net/http/cgi net/http/cookiejar net/http/fcgi net/http/httptest net/http/httptrace net/http/httputil net/http/internal net/http/pprof net/mail net/mail net/rpc net/rpc net/rpc/jsonrpc net/smtp net/smtp net/textproto net/textproto net/url net/url os os os/exec os/signal os/user path path path/filepath(文件路徑) plugin plugin(插件) reflect reflect(反射) regexp regexp(正則表達式) regexp/syntax runtime runtime(運行時) runtime/debug(調(diào)試) runtime/internal/sys runtime/pprof runtime/race(競爭) runtime/trace(執(zhí)行追蹤器) sort sort(排序算法) strconv strconv(轉(zhuǎn)換) strings strings(字符串) sync sync(同步) sync/atomic(原子操作) syscall syscall(系統(tǒng)調(diào)用) testing testing(測試) testing/iotest testing/quick text text/scanner(掃描文本) text/tabwriter text/template(定義模板) text/template/parse time time(時間戳) unicode unicode unicode/utf16 unicode/utf8 unsafe unsafe
characters

  • import "unsafe"

  • 概觀

  • 索引

概觀

軟件打包不安全包含圍繞 Go 程序類型安全的操作。

導(dǎo)入不安全的程序包可能不可移植,并且不受 Go 1 兼容性準則的保護。

索引

  • func Alignof(x ArbitraryType) uintptr

  • func Offsetof(x ArbitraryType) uintptr

  • func Sizeof(x ArbitraryType) uintptr

  • type ArbitraryType

  • type Pointer

打包文件

unsafe.go

func Alignof

func Alignof(x ArbitraryType) uintptr

Alignof 接受任何類型的表達式 x 并返回假設(shè)變量  v所需的對齊,就像 v 通過 var v = x 聲明一樣。它是最大的值 m,使得 v 的地址總是為零mod m。它與 reflect.TypeOf(x).Align() 返回的值相同。作為一種特殊情況,如果變量s是結(jié)構(gòu)類型,并且 f 是該結(jié)構(gòu)中的字段,那么 Alignof(s.f) 將返回結(jié)構(gòu)中該類型字段所需的對齊。這種情況與 reflect.TypeOf(s.f).FieldAlign() 返回的值相同。

func Offsetof

func Offsetof(x ArbitraryType) uintptr

Offsetof 返回由 x 表示的字段結(jié)構(gòu)中的偏移量,它必須是 structValue.field 的形式。換句話說,它返回結(jié)構(gòu)開始和字段開始之間的字節(jié)數(shù)。

func Sizeof

func Sizeof(x ArbitraryType) uintptr

Sizeof 采用任何類型的表達式x并返回假設(shè)變量 v 的字節(jié)大小,就像 v 通過 var v = x 聲明一樣。該大小不包括可能由 x 引用的任何內(nèi)存。例如,如果 x 是切片,則 Sizeof 返回切片描述符的大小,而不是切片引用的內(nèi)存大小。

type ArbitraryType

ArbitraryType 僅用于文檔目的,實際上并不是不安全軟件包的一部分。它表示任意 Go 表達式的類型。

type ArbitraryType int

type Pointer

指針表示指向任意類型的指針。類型指針有四種可用于其他類型的特殊操作:

- A pointer value of any type can be converted to a Pointer.- A Pointer can be converted to a pointer value of any type.- A uintptr can be converted to a Pointer.- A Pointer can be converted to a uintptr.

指針因此允許程序打敗類型系統(tǒng)并讀寫任意內(nèi)存。應(yīng)該非常小心地使用它。

涉及指針的以下模式是有效的。不使用這些模式的代碼今天可能無效,或在將來變得無效。即使下面的有效模式也有重要的注意事項。

運行“go vet”可以幫助找到不符合這些模式的指針的使用,但是從“go vet”沉默并不能保證代碼有效。

(1)將 * T1 轉(zhuǎn)換為 * T2 的指針。

假設(shè) T2 不大于 T1 并且兩者共享相同的存儲器布局,則該轉(zhuǎn)換允許將一種類型的數(shù)據(jù)重新解釋為另一種類型的數(shù)據(jù)。一個例子是 math.Float64bits 的實現(xiàn):

func Float64bits(f float64) uint64 {return *(*uint64)(unsafe.Pointer(&f))}

(2)將指針轉(zhuǎn)換為 uintptr(但不返回到指針)。

將指針轉(zhuǎn)換為 uintptr 會以整數(shù)形式生成指向的內(nèi)存地址。這種 uintptr 通常用于打印它。

將 uintptr 轉(zhuǎn)換回指針通常無效。

uintptr 是一個整數(shù),而不是引用。將指針轉(zhuǎn)換為 uintptr 將創(chuàng)建不帶指針語義的整數(shù)值。即使 uintptr 持有某個對象的地址,如果對象移動,垃圾收集器也不會更新該 uintptr 的值,uintptr 也不會使該對象不被回收。

其余模式枚舉從 uintptr 到指針的唯一有效轉(zhuǎn)換。

(3)用算術(shù)將指針轉(zhuǎn)換為 uintptr 并返回。

如果 p 指向已分配的對象,則可以通過轉(zhuǎn)換為 uintptr,添加偏移量以及轉(zhuǎn)換回指針來將對象前進。

p = unsafe.Pointer(uintptr(p) + offset)

這種模式最常見的用途是訪問結(jié)構(gòu)中的字段或數(shù)組中的元素:

// equivalent to f := unsafe.Pointer(&s.f)f := unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f))// equivalent to e := unsafe.Pointer(&x[i])e := unsafe.Pointer(uintptr(unsafe.Pointer(&x[0])) + i*unsafe.Sizeof(x[0]))

以這種方式添加和減去指針上的偏移量是有效的。使用 &^ 來循環(huán)指針也是有效的,通常用于對齊。在所有情況下,結(jié)果必須繼續(xù)指向原始分配的對象。

與 C 中不同的是,僅僅在它的原始分配結(jié)束時超前一個指針是無效的:

// INVALID: end points outside allocated space.var s thing
end = unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Sizeof(s))// INVALID: end points outside allocated space.b := make([]byte, n)end = unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(n))

請注意,這兩個轉(zhuǎn)換必須出現(xiàn)在相同的表達式中,只有它們之間的中間算術(shù):

// INVALID: uintptr cannot be stored in variable// before conversion back to Pointer.u := uintptr(p)p = unsafe.Pointer(u + offset)

(4)在調(diào)用 syscall.Syscall 時將指針轉(zhuǎn)換為 uintptr。

系統(tǒng)調(diào)用包中的 Syscall 函數(shù)直接將它們的 uintptr 參數(shù)傳遞給操作系統(tǒng),然后根據(jù)調(diào)用的細節(jié),將其中的一些重新解釋為指針。也就是說,系統(tǒng)調(diào)用實現(xiàn)隱式地將某些參數(shù)從 uintptr 轉(zhuǎn)換回指針。

如果必須將指針參數(shù)轉(zhuǎn)換為 uintptr 以用作參數(shù),則該轉(zhuǎn)換必須出現(xiàn)在調(diào)用表達式本身中:

syscall.Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(n))

編譯器處理一個轉(zhuǎn)換為 uintptr 的指針,轉(zhuǎn)換為在匯編中實現(xiàn)的函數(shù)的調(diào)用的參數(shù)列表中,通過安排被引用的已分配對象(如果有的話)被保留,直到調(diào)用完成時才移動,即使僅從類型在通話過程中將顯示該對象不再需要。

為了讓編譯器識別這種模式,轉(zhuǎn)換必須出現(xiàn)在參數(shù)列表中:

// INVALID: uintptr cannot be stored in variable// before implicit conversion back to Pointer during system call.u := uintptr(unsafe.Pointer(p))syscall.Syscall(SYS_READ, uintptr(fd), u, uintptr(n))

(5)將 reflect.Value.Pointer 或 reflect.Value.UnsafeAddr 的結(jié)果從 uintptr 轉(zhuǎn)換為指針。

Package 反射的 Value 方法名為 Pointer 和 UnsafeAddr,返回類型為 uintptr 而不是 unsafe.Pointer,以防止調(diào)用者將結(jié)果更改為任意類型,而不首先導(dǎo)入“unsafe”。但是,這意味著結(jié)果很脆弱,必須在調(diào)用后立即轉(zhuǎn)換為指針,并使用相同的表達式:

p := (*int)(unsafe.Pointer(reflect.ValueOf(new(int)).Pointer()))

與上述情況一樣,在轉(zhuǎn)換之前存儲結(jié)果無效:

// INVALID: uintptr cannot be stored in variable// before conversion back to Pointer.u := reflect.ValueOf(new(int)).Pointer()p := (*int)(unsafe.Pointer(u))

(6)將 Reflection.SliceHeader 或 reflect.StringHeader 數(shù)據(jù)字段轉(zhuǎn)換為指針或從指針轉(zhuǎn)換而來。

與前面的情況一樣,反射數(shù)據(jù)結(jié)構(gòu) SliceHeader 和 StringHeader 將字段 Data 聲明為 uintptr,以防止調(diào)用者在不首先導(dǎo)入“不安全”的情況下將結(jié)果更改為任意類型。但是,這意味著 SliceHeader 和 StringHeader 僅在解釋實際切片或字符串值的內(nèi)容時有效。

var s string
hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) // case 1hdr.Data = uintptr(unsafe.Pointer(p))              // case 6 (this case)hdr.Len = n

在這種用法中,hdr.Data 實際上是一種替代方法來引用片頭中的基礎(chǔ)指針,而不是 uintptr 變量本身。

一般來說,reflect.SliceHeader 和 reflect.StringHeader 只能用作 * reflect.SliceHeader 和 * reflect.StringHeader 指向?qū)嶋H的切片或字符串,而不能用作普通結(jié)構(gòu)。程序不應(yīng)該聲明或分配這些結(jié)構(gòu)類型的變量。

// INVALID: a directly-declared header will not hold Data as a reference.var hdr reflect.StringHeader
hdr.Data = uintptr(unsafe.Pointer(p))hdr.Len = n
s := *(*string)(unsafe.Pointer(&hdr)) // p possibly already lost
type Pointer *ArbitraryType
Previous article: Next article: