GoLang 強制類型轉換:unsafe.Pointer

注意此種轉換隻適合簡單類型,對於有對象描述的類型是徹底不適用的,雞肋啊ui

更詳細的文章請參見@陳一回 http://my.oschina.net/goal/blog/193698spa

ps:補充另一種用法,此次就不雞肋了.net

Go語言是個強類型語言。也就是說Go對類型要求嚴格,不一樣類型不能進行賦值操做。指針也是具備明確類型的對象,進行嚴格類型檢查。下面的代碼會產生編譯錯誤 指針

package main

import (
	"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方法能夠完成這個任務 code

package main

import (
	"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:發現一種用法,看代碼 blog

package main

import (
	"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)
}

輸出結果get

&{Bar <nil> <nil>  } &{Bar <nil> <nil>  }string

t.name 也變成 Bar了, 成功突破template.Template私有字段 nameio

相關文章
相關標籤/搜索