go类型转换及与C的类型转换方式
作者:this.Destroy() 发布时间:2024-04-28 09:18:38
GO类型转换及与C的类型转换
类型转换
语法
dst := float32(src)
示例
var num int = 520
f32 := float32(num)
i64 := int64(num)
注意:加入val是一个指针,int32(val)相当于*(int32(var1)),指针不能直接转换成一个int32类型,应该改为(*int32)(var1),所以某些类型可能引起误会的应该用括号括起来转换。
类型断言
语法
dst,ok := src.(int) // 安全类型断言,通过ok判断是否转换成功
dst := src.(int) // 非安全类型断言,无法确定是否转换成功
示例
var val interface{} = 123
num,ok := val.(int)
if ok {
fmt.Printf("%T->%d\n", num, num)
} else {
fmt.Println("类型不匹配")
}
其他转换
go提供了strconv包来进行转换
bytes 、string转换
//类型转换 string to bytes
func str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0], x[1], x[1]}
return *(*[]byte)(unsafe.Pointer(&h))
}
//类型转换 bytes to string
func bytes2str(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
interface转为string
//interface转为string
func interface2string(inter interface{}) string {
tempStr := ""
switch inter.(type) {
case string: tempStr = inter.(string) break
case float64: tempStr = strconv.FormatFloat(inter.(float64), 'f', -1, 64) break
case int64: tempStr = strconv.FormatInt(inter.(int64), 10) break
case int: tempStr = strconv.Itoa(inter.(int)) break
}
return tempStr
}
//整形转字符串
strconv.Itoa(100)
//该方法的源码是:
//可以看出是FormatInt方法的简单实现。
func Itoa(i int) string {
return FormatInt(int64(i), 10)
}
//字符串转整形
i, _ := strconv.Atoi("100")
//64位整形转字符串,FormatInt第二个参数表示进制,10表示十进制
var i int64
i = 0x100
strconv.FormatInt(i, 10)
//字节转32位整形
b := []byte{0x00, 0x00, 0x03, 0xe8}
bytesBuffer := bytes.NewBuffer(b)
//其中binary.BigEndian表示字节序,相应的还有little endian。通俗的说法叫大端、小端。
var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x)
fmt.Println(x)
//32位整形转字节
var x int32
x = 106
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, x)
fmt.Println(bytesBuffer.Bytes())
//字节转字符串
fmt.Println(string([]byte{97, 98, 99, 100}))
//字符串转字节
fmt.Println([]byte("abcd"))
string与unicode字符互转
//string-->unicode
func Str2uft16ptr(str string)(p uintptr){//将字符串转为utf16指针
e:=utf16.Encode([]rune(str))//转成unicode
e=append(e, uint16(0))//添加末尾的0
p=uintptr(unsafe.Pointer(&e[0]))//转成指针
//p=uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str)))
return
}
//unicode-->string
func addbuf(buf []uint16,newcap int)(newbuf []uint16){
newbuf=make([]uint16,newcap)
copy(newbuf,buf)
return
}
func Utf16prt2str(p uintptr)(str string){//将utf16指针转为字符串
len:=0
buf:=make([]uint16,64)
for a:=(*(*uint16)(unsafe.Pointer(p)));a!=0;len++{
if len>=cap(buf){
buf=addbuf(buf,len*2)
}
buf[len]=a
p+=2//uint16占2字节
a=(*(*uint16)(unsafe.Pointer(p)))
}
str=string(utf16.Decode(buf[:len]))
return
}
go和c类型装换
#cgo
char --> C.char --> byte
signed char --> C.schar --> int8
unsigned char --> C.uchar --> uint8
short int --> C.short --> int16
short unsigned int --> C.ushort --> uint16
int --> C.int --> int
unsigned int --> C.uint --> uint32
long int --> C.long --> int32 or int64
long unsigned int --> C.ulong --> uint32 or uint64
long long int --> C.longlong --> int64
long long unsigned int --> C.ulonglong --> uint64
float --> C.float --> float32
double --> C.double --> float64
wchar_t --> C.wchar_t -->
void * -> unsafe.Pointer
#window
uint64 //对应SIZE_T
uint32 //对应DWORD
//整型数
//Go->C:
var i int
ci := C.int(i)
//C->Go:
var i C.int
goi := int(i)
//数组和字符串
//Go->C:
var str string
cstr := C.CString(str)
//C->Go:
/*
#include <stdlib.h>
#include <stdio.h>
char foo[] = "hellofoo";
char *bar = "hellobar";
*/
import "C"
import "fmt"
func main() {
fmt.Printf("%s\n", C.GoString(&C.foo[0]))
fmt.Printf("%s\n", C.GoString(C.bar))
}
//数组类型转换
/*
#include <stdio.h>
int cIArray[] = {1, 2, 3, 4, 5, 6, 7}; //int
float cFArray[] = {1.011, 2.022, 3.022, 4.023, 5.02, 6.03, 7.045};//float
*/
import "C"
import "fmt"
func main() {
goIArray := C.cIArray[:]
fmt.Println(goIArray)
goFArray := C.cFArray[:]
fmt.Println(goFArray)
}
//[]byte 转换为 *char
c_char := (*C.char)(unsafe.Pointer(&bt[0]))
fmt格式字符串:
打印格式 | 含义 |
---|---|
%% | 一个%字面量 |
%b | 一个二进制整数值(基数为2),或者是一个(高级的)用科学计数法表示的指数为2的浮点数 |
%c | 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符 |
%d | 一个十进制数值(基数为10) |
%e | 以科学记数法e表示的浮点数或者复数值 |
%E | 以科学记数法E表示的浮点数或者复数值 |
%f | 以标准记数法表示的浮点数或者复数值 |
%g | 以%e或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出 |
%G | 以%E或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出 |
%o | 一个以八进制表示的数字(基数为8) |
%p | 以十六进制(基数为16)表示的一个值的地址,前缀为0x,字母使用小写的a-f表示 |
%q | 使用Go语法以及必须时使用转义,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字 |
%s | 字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符) |
%t | 以true或者false输出的布尔值 |
%T | 使用Go语法输出的值的类型 |
%U | 一个用Unicode表示法表示的整型码点,默认值为4个数字字符 |
%v | 使用默认格式输出的内置或者自定义类型的值,或者是使用其类型的String()方式输出的自定义值,如果该方法存在的话 |
%x | 以十六进制表示的整型值(基数为十六),数字a-f使用小写表示 |
%X | 以十六进制表示的整型值(基数为十六),数字A-F使用小写表示 |
强制转换 | 隐式转换 | 类型断言 | |
---|---|---|---|
类型之间 | 可以 | 不可以 | 可以 |
类型->接口 | 可以 | 可以 | 可以 |
接口->类型 | 不可以 | 不可以 | 可以 |
接口之间 | 可以(编译期间确定) | 可以(编译期间确定) | 可以 |
补充:Golang常见类型转换
1.Type(expression):
int(time.Now().Weekday()) //星期转int
int(time.Now().Month()) //月份转int
var a float64
a = 3.1
b := int(a) //float64转int
var a int
a = 1
b := int64(a) //int转int64
2.strconv包:
string和int、int32、int64:
i, _ := strconv.Atoi(s) //string转int
s := strconv.Itoa(i) //int转string
i, _ := strconv.ParseInt(s, 10, 32) //string转int32
ii := int32(I)
i, _ := strconv.ParseInt(s, 10, 64) //string转int32
s := strconv.FormatInt(i, 10) //int64转string
ParseInt函数的官方介绍:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
–返回字符串表示的整数值,接受正负号。
–base指定进制(2到36),如果base为0,则会从字符串前置判断,"0x"是16进制,"0"是8进制,否则是10进制。
–bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64。
–返回的err是*NumErr类型的,如果语法有误,err.Error = ErrSyntax;如果结果超出类型范围err.Error = ErrRange。
FormatInt函数中的10,表示10进制。
string和float32、float64:
f, _ := strconv.ParseFloat(s, 32) //string转float32
ff := float32(f)
f, _ := strconv.ParseFloat(s, 64) //string转float64
s := strconv.FormatFloat(f, 'f', -1, 64) //float64转string
ParseFloat函数的官方介绍:
func ParseFloat(s string, bitSize int) (f float64, err error)
–解析一个表示浮点数的字符串并返回其值。
–如果s合乎语法规则,函数会返回最为接近s表示值的一个浮点数(使用IEEE754规范舍入)。
–bitSize指定了期望的接收类型,32是float32(返回值可以不改变精确值的赋值给float32),64是float64。
–返回值err是*NumErr类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值f为±Inf,err.Error= ErrRange。
FormatFloat函数的官方介绍:
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
–bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。
–fmt表示格式:‘f'(-ddd.dddd)、‘b'(-ddddp±ddd,指数为二进制)、‘e'(-d.dddde±dd,十进制指数)、‘E'(-d.ddddE±dd,十进制指数)、‘g'(指数很大时用'e'格式,否则'f'格式)、‘G'(指数很大时用'E'格式,否则'f'格式)。
–prec控制精度(排除指数部分):对'f'、‘e'、‘E',它表示小数点后的数字个数;对'g'、‘G',它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。
string和time:
t, _ := time.Parse("2006-01-02 15:04:05", s) //string转时间
t, _ := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local) //string转本地时间
s := t.Format("2006-01-02 15:04:05") //时间转string
3.类型断言:expression.(Type):
expression必须是接口类型,且自身类型与Type类型相符。
expression.(Type)的返回值一般为两个:value和ok,匹配成功ok为true,value有值,匹配失败ok为false,value无值;也可以直接接受value一个返回值,不过失败则直接panic:
func main() {
var a interface{} = 100
if aa, ok := a.(int); ok {
fmt.Println(aa)
}
}
还可以结合switch和case使用,来判断接口实际类型:
func main() {
var t interface{} = 100
switch i := t.(type) {
case float32:
fmt.Printf("i的类型%T i的值%v\n", i, i)
case float64:
fmt.Printf("i的类型%T i的值%v\n", i, i)
case int:
fmt.Printf("i的类型%T i的值%v\n", i, i)
case bool:
fmt.Printf("i的类型%T i的值%v\n", i, i)
case string:
fmt.Printf("i的类型%T i的值%v\n", i, i)
default:
fmt.Println("其他类型")
}
}
4.JSON:
Golang中大多数数据类型都可以转化为有效的JSON文本,除了channel通道、complex复数、func函数等。
Golang指针可进行隐式转换,表面进行的是指针序列化,内部会针对指针进行取值操作,实际还是针对所指的对象进行序列化。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持asp之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/wyy626562203/article/details/83792470


猜你喜欢
- pyecharts介绍pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。
- 引言前几天忽然想到了四则运算和二树有没有关系,然后在网络上检索了一下,发现还真的有四则运算和二叉树。因为总是见到把 四则运算表达式 用 树
- 大多数情况下,我们使用 webpack来打包单页应用程序,这个时候只需要配置一个入口,一个模板文件,但也不尽是如此,有时候也会碰到多页面的项
- 本文给出一条 SQL 语句用于展示在同一名服务器上,不同的数据库间查询,注意当前连接用户要对两个库都有权限SQL Server 中 SQL
- python中同样使用关键字class创建一个类,类名称第一个字母大写,可以带括号也可以不带括号;python中实例化类不需要使用关键字ne
- 特地查看了下手册,关于php magic quotes,常见的几个设置如下,magic_quotes_gpc,magic_quo
- 有时候在一个页面用到收放功能的时候时,总有一个虚线框在触发收放的功能按钮上,显得特别刺眼,那如何去除这个虚线框呢?在IE下,需要在标签 a
- 前言段(segment)是一种在数据库中消耗物理存储空间的任何实体(一个段可能存在于多个数据文件中,因为物理的数据文件是组成逻辑表空间的基本
- 1. 为什么不使用GridView的默认分页功能 首先要说说为什么不用GridView的默认的分页功能,GridView控件并非真正知道如何
- 老生常谈的问题,大部分人也不一定可以系统的理解。Javascript语言对继承实现的并不好,需要工程师自己去实现一套完整的继承机制。下面我们
- 前言Iframe 是一种将网页嵌入到另一个页面的内容中的方法。这是通过使用 HTML 元素、外部网站的 URL 以及窗口在您的网站上的外观参
- 新标准的熟悉和入门内容: 还在用 HTML 编写文档?如果是的话,就不符合当前标准了。2000 年&
- 本文实例讲述了使用symfony命令创建项目的方法。分享给大家供大家参考,具体如下:概况这一章节描述一个Symfony项目的合理结构框架,并
- 目录前言 字符串都有哪些操作?第一类 判断识别字符串第二类 字符串编辑的操作第三类:字符串跟字节串的互转总结前言今天我们说了字符串
- 本文实例讲述了JS基于开关思想实现的数组去重功能。分享给大家供大家参考,具体如下:场景: 比如给你一个数组var Arr = [ 25, 7
- 开发工具Python版本:3.6.4相关模块:cv2模块;以及一些Python自带的模块。环境搭建安装Python并添加到环境变量,pip安
- UUID(Universally Unique Identifier)是通用唯一识别码,在许多领域用作标识,比如我们常用的数据库也可以用它来
- 概述在列表复制这个问题,看似简单的复制却有着许多的学问,尤其是对新手来说,理所当然的事情却并不如意,比如列表的赋值、复制、浅拷贝、深拷贝等绕
- Mysql的Bin log数据恢复:不小心删除数据库前言:因为不小心删除了测试机器上Mysql的一整个数据库Schema,因为是测试机所以没
- 本文介绍了一种将英文字符首个字母串转换为大写的asp代码,当然这个功能可能英文网站比较有用。转换大写功能英文介绍:Code Title: P