文档章节

GoLang 强制类型转换:unsafe.Pointer

喻恒春
 喻恒春
发布于 2013/04/13 15:18
字数 383
阅读 11620
收藏 12

注意此种转换只适合简单类型,对于有对象描述的类型是完全不适用的,鸡肋啊

更详细的文章请参见@陈一回 http://my.oschina.net/goal/blog/193698

ps:补充另外一种用法,这次就不鸡肋了

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方法可以完成这个任务

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:发现一种用法,看代码

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)
}

输出结果

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

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


© 著作权归作者所有

共有 人打赏支持
喻恒春

喻恒春

粉丝 106
博文 29
码字总数 21951
作品 5
郑州
程序员
私信 提问
加载中

评论(2)

smart_w
smart_w
突破私有变量很不错
一曲
一曲
不错,学习!
golang: 利用unsafe操作未导出变量

看了 @喻恒春 大神的利用unsafe.Pointer来突破私有成员,觉得例子举得不太好。而且不应该简单的放个demo,至少要讲一下其中的原理,让看的童鞋明白所以然。see:http://my.oschina.net/achun...

陈亦
2014/01/17
0
10
Go之unsafe.Pointer && uintptr类型

Go之unsafe.Pointer && uintptr类型 unsafe.Pointer 这个类型比较重要,它是实现定位欲读写的内存的基础。官方文档对该类型有四个重要描述: 大多数指针类型会写成T,表示是“一个指向T类型变...

秋风醉了
2016/08/08
184
0
Go语言中使用C语言函数

go编译器有两套:go自带的和gccgo。其中gccgo是以gcc为后端,编译后的go代码可以和 gcc编译的C/C++代码集成。go自带的编译器中有一个叫cgo的工具,可以用于在go中集成C 语言库。 在go中如果需...

曾赛
2010/04/27
1K
2
cgo的一些经验

cgo可以在go语言中夹杂着C函数或数据,在使用cgo时,有一些需要注意的: 1、go中的int/int32/int64/uint32/uint64和C语言中的int/int32等是不同的,因此,C语言的函数的参数不能是go语言的i...

徐学良
2015/12/25
67
0
【go语言】wait,why not safe

slice?俺知道,不就是基于数组的一个视窗嘛! 出个题呗~ 好~ package main func main() { var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s := arr[2:6] modify(s) } func modify(tmp []......

qingkechina
2017/02/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
10
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
16
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
15
0
CompletableFuture get方法一直阻塞或抛出TimeoutException

问题描述 最近刚刚上线的服务突然抛出大量的TimeoutException,查询后发现是使用了CompletableFuture,并且在执行future.get(5, TimeUnit.SECONDS);时抛出了TimeoutException异常,导致接口响...

xiaolyuh
今天
8
0
dubbo 搭建与使用

官网:http://dubbo.apache.org/en-us/ 一,安装监控中心(可以不安装) admin管理控制台,monitor监控中心 下载 bubbo ops 这个是新版的,需要node.js环境,我没有就用老版的了...

小兵胖胖
今天
16
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部