Go 数据类型和类型转换

gongwz · · 925 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

# Go 数据类型和类型转换 Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、`map`、通道(channel)等。Go 语言的基本类型和其他语言大同小异。 ## 整型 整型分为以下两个大类: 按长度分为:int8、int16、int32、int64 对应的无符号整型:uint8、uint16、uint32、uint64 其中,uint8 就是我们熟知的 byte型,int16 对应 C语言中的 short型,int64对应C语言中的 long型。 <img src = 'https://static.studygolang.com/190824/5347c32cc4c5eb6e58c0be3ae63b321f.png' width="70%"></img> ## 特殊整型 <img src = 'https://static.studygolang.com/190824/067a6a1cc1dabd7ff15de1da59ed7d4f.png' width="60%"></img> **注意**: 在使用int和 uint类型时,不能假定它是32位或64位的整型,而是考虑int和uint可能在不同平台上的差异。 **注意事项**:获取对象的长度的内建len()函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以用int来表示。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int和 uint。 ## 八进制&十六进制 Go语言中无法直接定义二进制数,关于八进制和十六进制数的示例如下: ```go package main import "fmt" func main(){ // 十进制 var a int = 10 fmt.Printf("%d \n", a) // 10 fmt.Printf("%b \n", a) // 1010 占位符%b表示二进制 // 八进制 以0开头 var b int = 077 fmt.Printf("%o \n", b) // 77 // 十六进制 以0x开头 var c int = 0xff fmt.Printf("%x \n", c) // ff fmt.Printf("%X \n", c) // FF } ``` ## 浮点型 Go语言支持两种浮点型数:float32和float64。这两种浮点型数据格式遵循IEEE 754标准: float32 的浮点数的最大范围约为 3.4e38,可以使用常量定义:math.MaxFloat32。 float64 的浮点数的最大范围约为 1.8e308,可以使用一个常量定义:math.MaxFloat64。 打印浮点数时,可以使用fmt包配合动词%f,代码如下: ``` go package main import ( "fmt" "math" ) func main() { fmt.Printf("%f\n", math.Pi) fmt.Printf("%.2f\n", math.Pi) } ``` ## 复数 **complex64和complex128** ```go var c1 complex64 c1 = 1 + 2i var c2 complex128 c2 = 2 + 3i fmt.Println(c1) fmt.Println(c2) ``` > 复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。 ## 布尔型 Go语言中以 bool 类型进行声明布尔型数据,布尔型数据只有true(真)和false(假)两个值。 **注意**: - 布尔类型变量的默认值为false。 - Go 语言中不允许将整型强制转换为布尔型. - 布尔型无法参与数值运算,也无法与其他类型进行转换。 ## 字符串 Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64 等)一样。 Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为双引号(")中的内容,可以在Go语言的源码中直接添加非ASCII码字符,例如: ```go s1 := "hello" s2 := "你好" ``` ### 字符串转义 <img src = 'https://static.studygolang.com/190824/5bb68d5dc48df2606ff34cc027eef7ab.png' width="60%"></img> ### 多行字符串 Go语言中要定义一个多行字符串时,就必须使用反引号字符: 反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。 ```go s1 := `第一行 第二行 第三行 ` fmt.Println(s1) ``` ### 字符串的常用操作 <img src = 'https://static.studygolang.com/190824/3a84729d8ea5d8310a55e09c1c59fff3.png' width="70%"></img> ## byte和rune类型 组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(’)包裹起来,如: ```go var a := '中' var b := 'x' ``` Go 语言的字符有以下两种: - uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。 - rune类型,代表一个 UTF-8字符。 当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32。 Go 使用了特殊的 rune 类型来处理 Unicode,让基于 Unicode 的文本处理更为方便,也可以使用 byte 型进行默认字符串处理,性能和扩展性都有照顾。 ```go // 遍历字符串 func traversalString() { s := "hello中国" for i := 0; i < len(s); i++ { //byte fmt.Printf("%v(%c) ", s[i], s[i]) } fmt.Println() for _, r := range s { //rune fmt.Printf("%v(%c) ", r, r) } fmt.Println() } ``` 打印结果: ``` 104(h) 101(e) 108(l) 108(l) 111(o) 228(ä) 184(¸) 173(•) 229(å) 155(•) 189(½) 104(h) 101(e) 108(l) 108(l) 111(o) 20013(中) 22269(国) ``` 因为UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面输出中第一行的结果。 字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。 ### 修改字符串 要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。 ```go func changeString() { s1 := "big" // 强制类型转换 byteS1 := []byte(s1) byteS1[0] = 'p' fmt.Println(string(byteS1)) s2 := "白萝卜" runeS2 := []rune(s2) runeS2[0] = '红' fmt.Println(string(runeS2)) } ``` ## 类型转换 Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。 强制类型转换的基本语法如下: ``` T(表达式) ``` 其中,T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等. 比如计算直角三角形的斜边长时使用math包的Sqrt()函数,该函数接收的是float64类型的参数,而变量a和b都是int类型的,这个时候就需要将a和b强制类型转换为float64类型。 ## 练习题 **1、编写代码分别定义一个整型、浮点型、布尔型、字符串型变量,使用fmt.Printf()搭配%T分别打印出上述变量的值和类型** **2、编写代码统计出字符串"hello沙河小王子"中汉字的数量** ## 笔记 ```go /** * @Author: Weizhen * @Date: 2019-08-24 10:18 **/ package main import ( "fmt" "math" ) // 遍历字符串 func traversal_string() { s := "hello中国" for i := 0; i < len(s); i++ { //byte fmt.Printf("%v(%c) ", s[i], s[i]) } fmt.Println() for _, r := range s { //rune fmt.Printf("%v(%c) ", r, r) } fmt.Println() } // 修改字符串 func changeString() { s1 := "big" // 强制类型转换 byteS1 := []byte(s1) byteS1[0] = 'p' fmt.Println(string(byteS1)) s2 := "白萝卜" runeS2 := []rune(s2) runeS2[0] = '红' fmt.Println(string(runeS2)) } func main() { fmt.Println("整型 ----> ") var a int = 10 var b int = 077 var c int = 0xff fmt.Printf("%d \n",a) // 10 fmt.Printf("%b \n",a) // 1010 占位符 %b 表示二进制 fmt.Println(a, b, c) // 10 63 255 fmt.Printf("%o\n", b) // 77 fmt.Printf("%x\n", c) // ff fmt.Printf("%p\n", &c) // 求c变量的内存地址 0xc000016060 fmt.Println("浮点型 ----> ") fmt.Printf("%f \n",math.Pi) // 3.141593 fmt.Printf("%.2f \n",math.Pi) // 3.14 fmt.Println(math.MaxFloat64) // 1.7976931348623157e+308 fmt.Println(math.MaxFloat32) // 3.4028234663852886e+38 fmt.Println("复数 ----> ") var c1 complex64 c1 = 1 + 2i fmt.Println(c1) // (1+2i) fmt.Println("字符串 --->") fmt.Println("str := \"c:\\Code\\lesson1\\go.exe\"") // 打印一个路径字符串 var s1 = `第一行 第二行/n \n` fmt.Println(s1) // 打印多行字符串,转义字符均无效,会原样输出 traversal_string() // 引用遍历上面字符串的函数 changeString() } ``` 参考来源 > [原文参考](https://www.liwenzhou.com/posts/Go/12_datatype/ "李文周") > [Typeof参考](https://studygolang.com/articles/14269 )

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

925 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传