這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
注意此種轉換隻適合簡單類型,對於有對象描述的類型是完全不適用的,雞肋啊
更詳細的文章請參見@陳一回 http://my.oschina.net/goal/blog/193698
ps:補充另外一種用法,這次就不雞肋了
Go語言是個強型別語言。也就是說Go對類型要求嚴格,不同類型不能進行賦值操作。指標也是具有明確類型的對象,進行嚴格類型檢查。下面的代碼會產生編譯錯誤
package mainimport ( "fmt")func main() { u := uint32(32) i := int32(1) fmt.Println(&u, &i) // 列印出地址 p := &i // p 的類型是 *int32 p = &u // &u的類型是 *uint32,於 p 的類型不同,不能賦值 p = (*int32)(&u) // 這種類型轉換文法也是無效的 fmt.Println(p)}
unsafe 包提供的Pointer方法可以完成這個任務
package mainimport ( "fmt" "unsafe")func main() { u := uint32(32) i := int32(1) fmt.Println(&u, &i) p := &i p = (*int32)(&u) p = (*int32)(unsafe.Pointer(&u)) fmt.Println(p)}
補充:實際使用中unsafe可用情境很少,稍微複雜一點的結構,比如struct,unsafe根本不能適用,正確的方法還是要靠 type assertion
ps:發現一種用法,看代碼
package mainimport ( "fmt" "text/template" "unsafe")// MyTemplate 定義和 template.Template 只是形似type MyTemplate struct { name string parseTree *unsafe.Pointer common *unsafe.Pointer leftDelim string rightDelim string}func main() { t := template.New("Foo") p := (*MyTemplate)(unsafe.Pointer(t)) p.name = "Bar" // 關鍵在這裡,突破私人成員 fmt.Println(p, t)}
輸出結果
&{Bar <nil> <nil> } &{Bar <nil> <nil> }
t.name 也變成 Bar了, 成功突破template.Template私人欄位 name