1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 04:22:22 +00:00

Merge pull request #327 from fuwensun/pr2-3-1f

ch2-3-fix typos
This commit is contained in:
chai2010 2018-08-21 20:04:42 +08:00 committed by GitHub
commit 75ff1c9924
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,6 @@
# 2.3 类型转换
最初CGO是为了达到方便从Go语言函数调用C语言函数以复用C语言资源这一目的而出现的(因为C语言还会涉及回调函数自然也会涉及到从C语言函数调用Go语言函数)。现在它已经演变为C语言和Go语言双向通讯的桥梁。要想利用好CGO特性自然需要了解此二语言类型之间的转换规则这是本节要讨论的问题。
最初CGO是为了达到方便从Go语言函数调用C语言函数用C语言实现Go语言声明的函数以复用C语言资源这一目的而出现的因为C语言还会涉及回调函数自然也会涉及到从C语言函数调用Go语言函数用Go语言实现C语言声明的函数。现在它已经演变为C语言和Go语言双向通讯的桥梁。要想利用好CGO特性自然需要了解此二语言类型之间的转换规则这是本节要讨论的问题。
## 2.3.1 数值类型
@ -71,7 +71,7 @@ typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
```
不过需要注意的是其中只有字符串和切片在CGO中有一定的使用价值因为此二者可以在Go调用C语言函数时马上使用;而CGO并未针对其他的类型提供相关的辅助函数且Go语言特有的内存模型导致我们无法保持这些由Go语言管理的内存指针所以它们C语言环境并无使用的价值。
不过需要注意的是其中只有字符串和切片在CGO中有一定的使用价值因为CGO为他们的某些GO语言版本的操作函数生成了C语言版本此二者可以在Go调用C语言函数时马上使用;而CGO并未针对其他的类型提供相关的辅助函数且Go语言特有的内存模型导致我们无法保持这些由Go语言管理的内存指针所以它们C语言环境并无使用的价值。
在导出的C语言函数中我们可以直接使用Go字符串和切片。假设有以下两个导出函数
@ -364,7 +364,7 @@ typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
在Go语言中两个指针的类型完全一致则不需要转换可以直接通用。如果一个指针类型是用type命令在另一个指针类型基础之上构建的换言之两个指针底层是相同完全结构的指针那么我我们可以通过直接强制转换语法进行指针间的转换。但是cgo经常要面对的是2个完全不同类型的指针间的转换原则上这种操作在纯Go语言代码是严格禁止的。
cgo存在的一个目的就是打破Go语言的禁恢复C语言应有的指针的自由转换和指针运算。以下代码演示了如何将X类型的指针转化为Y类型的指针
cgo存在的一个目的就是打破Go语言的禁恢复C语言应有的指针的自由转换和指针运算。以下代码演示了如何将X类型的指针转化为Y类型的指针
```go
var p *X
@ -402,9 +402,9 @@ p = (*X)(unsafe.Pointer(q)) // *Y => *X
## 2.3.7 切片间的转换
在C语言中数组也一种指针因此两个不同类型数组之间到转换和指针间转换基本类似。但是在Go语言中数组或数组对应到切片都不再是指针类型因为我们也就无法直接实现不同类型到切片之间的转换。
在C语言中数组也一种指针因此两个不同类型数组之间的转换和指针间转换基本类似。但是在Go语言中数组或数组对应的切片都不再是指针类型因此我们也就无法直接实现不同类型的切片之间的转换。
不过Go语言的reflect包提供了切片类型到底层结构,再结合前面讨论到不同类型之间到指针转换技术就可以实现`[]X``[]Y`类型的切片转换:
不过Go语言的reflect包提供了切片类型的底层结构,再结合前面讨论到不同类型之间的指针转换技术就可以实现`[]X``[]Y`类型的切片转换:
```go
var p []X
@ -418,7 +418,7 @@ pHdr.Len = qHdr.Len * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0])
pHdr.Cap = qHdr.Cap * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0])
```
不同切片类型之间转换到思路是先为构造一个空的目标切片然后用原有的切片底层数据填充目标切片。如果X和Y类型的大小不同需要重新设置Len和Cap属性。需要注意的是如果X或Y是空类型上述代码中可能导致除0错误实际代码需要根据情况酌情处理。
不同切片类型之间转换的思路是先构造一个空的目标切片然后用原有的切片底层数据填充目标切片。如果X和Y类型的大小不同需要重新设置Len和Cap属性。需要注意的是如果X或Y是空类型上述代码中可能导致除0错误实际代码需要根据情况酌情处理。
下面演示了切片间的转换的具体流程: