什么是go的反射?

什么是go的反射?,第1张

基础

反射是在运行期间获取类的各种信息。

Go语言的反射需要理解两个概念Type和Value,它们也是Go语言中reflect空间里最重要的两个类型,举例如下:

 type MyReader struct { 
     Name string
​
 } 
func (r MyReader)Read(p []byte) (n int, err error) { 
 // 实现自己的Read方法
}
var reader io.Reader 
reader = &MyReader{"a.txt"}
​

对所有接口进行反射,都可以得到一个包含Type和Value的信息结构。比如对上例的reader进行反射,也将得到一个Type和Value,Type为io.Reader,Value为MyReader{“a.txt”}。顾名思义,Type主要表达的是被反射的这个变量本身的类型信息,而Value则为该变量实例本身的信息。

语言交互性

自c语言诞生以来,后面有无数的新的语言实现,但是大部分的语言底层都封装了本地方法调用底层的C语言的方法,比如java提供了JNI机制来调用那些C代码库,Go语言也提供了对C语言的调用,称为Cgo,举例如下:

package main
​
import "fmt"
​
/*
#include 
*/
import "C"
​
func Random() int {
    return int(C.random())
}
func Seed(i int) {
    C.srandom(C.uint(i))
}
func main() {
    Seed(100)
    fmt.Println("Random:", Random())
}
类型映射

类型映射是指两种语言交互,两种语言之间变量的转换关系,比如Go语言的string类型需要跟c语言中的字符数组进行对应,并且要保证映射到C语言的对象的生命周期足够长,以避免在C语言执行过程中该对象就已经被垃圾回收。对于C语言的原生类型,Cgo都会将其映射为Go语言中的类型,知道有这种对应关系就行。

字符串映射

因为Go语言中有明确的string原生类型,而C语言中用字符数组表示,Cgo提供了一系列函数来提供支持:C.CString、C.GoString和C.GoStringN。注意的是string每次的转换都是一次内存复制,字符串其实是不能修改的,比如java中的string两个值的拼接,不是修改原来的string的的值,而是新申请内存空间去存相加后的值,所有用到C.CString的代码大致都可以写成如下的风格:

var gostr string
// ... 初始化gostr 
cstr := C.CString(gostr) 
defer C.free(unsafe.Pointer(cstr)) 
// 接下来大胆地使用cstr吧,因为保证可以被释放掉了
// C.sprintf(cstr, "content is: %d", 123)
​
C程序

需要在Go语言调用任何C代码都可以在注释里面写C语言的代码直接调用如下:

package hello 
/* 
#include  
void hello() { 
 printf("Hello, Cgo! -- From C world.\n"); 
} 
*/ 
import "C" 
func Hello() int { 
 return int(C.hello()) 
}

主要是/**/之间的内容是写c语言的代码块,如果需要在这个c语言代码块调用非c语言的需求,Cgo提供了#cgo一种伪C文法,让开发者有机会指定依赖的第三方库和编译选项如下:

// #cgo CFLAGS: -DPNG_DEBUG=1 
// #cgo linux CFLAGS: -DLINUX=1 
// #cgo LDFLAGS: -lpng 
// #include  
import "C"
函数调用

常规的调用直接函数名加上需要传递的参数就好,比如有错误的返回值的调用为:

n, err := C.atoi("a234")

在传递数组类型的参数时需要注意,在Go语言中将第一个元素的地址作为整个数组的起始地址传入,这一点就不如C语言本身直接传入数组名字那么方便了。如下:

n, err := C.f(&array[0]) // 需要显示指定第一个元素的地址
编译Cgo

编译Cgo代码非常容易,不需要做任何特殊的处理。Go安装后,会自带一个cgo命令行工具,它用于处理所有带有Cgo代码的Go文件,生成Go语言版本的调用封装代码。而Go工具集对cgo命令行工具再次进行了良好的封装,使构建过程能够自动识别和处理带有Cgo代码的Go源代码文件,完全不给用户增加额外的工作负担。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/990705.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存