注意此种转换只适合简单类型,对于有对象描述的类型是完全不适用的,鸡肋啊
ps:补充另外一种用法,这次就不鸡肋了
Go语言是个强类型语言。也就是说Go对类型要求严格,不同类型不能进行赋值操作。指针也是具有明确类型的对象,进行严格类型检查。下面的代码会产生编译错误
01 | package main |
02 |
03 | import ( |
04 | "fmt" |
05 | ) |
06 |
07 | func main() { |
08 | u := uint32(32) |
09 | i := int32(1) |
10 | fmt.Println(&u, &i) // 打印出地址 |
11 | p := &i // p 的类型是 *int32 |
12 | p = &u // &u的类型是 *uint32,于 p 的类型不同,不能赋值 |
13 | p = (*int32)(&u) // 这种类型转换语法也是无效的 |
14 | fmt.Println(p) |
15 | } |
01 | package main |
02 |
03 | import ( |
04 | "fmt" |
05 | "unsafe" |
06 | ) |
07 |
08 | func main() { |
09 | u := uint32(32) |
10 | i := int32(1) |
11 | fmt.Println(&u, &i) |
12 | p := &i |
13 | p = (*int32)(&u) |
14 | p = (*int32)(unsafe.Pointer(&u)) |
15 | fmt.Println(p) |
16 | } |
补充:实际使用中unsafe可用场景很少,稍微复杂一点的结构,比如struct,unsafe根本不能适用,正确的方法还是要靠 type assertion
ps:发现一种用法,看代码
01 | package main |
02 |
03 | import ( |
04 | "fmt" |
05 | "text/template" |
06 | "unsafe" |
07 | ) |
08 | // MyTemplate 定义和 template.Template 只是形似 |
09 | type MyTemplate struct { |
10 | name string |
11 | parseTree *unsafe.Pointer |
12 | common *unsafe.Pointer |
13 | leftDelim string |
14 | rightDelim string |
15 | } |
16 |
17 | func main() { |
18 | t := template .New( "Foo" ) |
19 | p := (*My<span></span>Template<span></span>)(unsafe.Pointer(t)) |
20 | p.name = "Bar" // 关键在这里,突破私有成员 |
21 | fmt.Println(p, t) |
22 | } |