李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
GO
正文
04.Golang基本数据类型
Leefs
2022-06-28 PM
1420℃
0条
[TOC] ### 前言 ![04.GO语言基本数据类型01.jpeg](https://lilinchao.com/usr/uploads/2022/06/1482323926.jpeg) 在静态类型语言(C++/Java/Golang 等)中规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。 ### 一、整形 **整型分两大类** - **有符号整型**:`int8`、`int16`、`int32`、`int64`、int。 - **无符号整型**:`uint8`、`uint16`、`uint32`、`uint64`、`uint`。 ![04.GO语言基本数据类型02.jpg](https://lilinchao.com/usr/uploads/2022/06/1685480059.jpg) **注意:** 在使用`int`和 `uint`类型时,不能假定它是32位或64位的整型,而是考虑`int`和`uint`可能在不同平台上的差异。 表示范围:在 `32` 位系统下是 `-2147483648` ~ `2147483647` ,而在 `64` 位系统是 `-9223372036854775808` ~ `9223372036854775807` 。 **注意事项** 获取对象的长度的内建`len()`函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以用`int`来表示。 **在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用`int`和 `uint`。** **示例** ```go package main import ( "fmt" "math" "unsafe" ) // 有符号整型 func Integer() { var num8 int8 = 127 var num16 int16 = 32767 var num32 int32 = math.MaxInt32 var num64 int64 = math.MaxInt64 var num int = 100 fmt.Printf("num8的类型是 %T, num8的大小 %d, num8是 %d\n", num8, unsafe.Sizeof(num8), num8) fmt.Printf("num16的类型是 %T, num16的大小 %d, num16是 %d\n", num16, unsafe.Sizeof(num16), num16) fmt.Printf("num32的类型是 %T, num32的大小 %d, num32是 %d\n", num32, unsafe.Sizeof(num32), num32) fmt.Printf("num64的类型是 %T, num64的大小 %d, num64是 %d\n", num64, unsafe.Sizeof(num64), num64) fmt.Printf("num的类型是 %T, num的大小 %d, num是 %d\n", num, unsafe.Sizeof(num), num) } // 无符号整型 func unsignedInteger() { var num8 uint8 = 128 var num16 uint16 = 32768 var num32 uint32 = math.MaxUint32 var num64 uint64 = math.MaxUint64 var num uint = 100 fmt.Printf("num8的类型是 %T, num8的大小 %d, num8是 %d\n", num8, unsafe.Sizeof(num8), num8) fmt.Printf("num16的类型是 %T, num16的大小 %d, num16是 %d\n", num16, unsafe.Sizeof(num16), num16) fmt.Printf("num32的类型是 %T, num32的大小 %d, num32是 %d\n", num32, unsafe.Sizeof(num32), num32) fmt.Printf("num64的类型是 %T, num64的大小 %d, num64是 %d\n", num64, unsafe.Sizeof(num64), num64) fmt.Printf("num的类型是 %T, num的大小 %d, num是 %d\n", num, unsafe.Sizeof(num), num) } func main() { Integer() fmt.Println("--------------------------------") unsignedInteger() } ``` **运行结果** ``` num8的类型是 int8, num8的大小 1, num8是 127 num16的类型是 int16, num16的大小 2, num16是 32767 num32的类型是 int32, num32的大小 4, num32是 2147483647 num64的类型是 int64, num64的大小 8, num64是 9223372036854775807 num的类型是 int, num的大小 8, num是 100 -------------------------------- num8的类型是 uint8, num8的大小 1, num8是 128 num16的类型是 uint16, num16的大小 2, num16是 32768 num32的类型是 uint32, num32的大小 4, num32是 4294967295 num64的类型是 uint64, num64的大小 8, num64是 18446744073709551615 num的类型是 uint, num的大小 8, num是 100 ``` ### 二、浮点型 浮点型表示存储的数据是实数,如 3.145。关于浮点型的说明,如表所示。 | 类型 | 字节数 | 说明 | | ------- | ------ | ------------- | | float32 | 4 | 32 位的浮点型 | | float64 | 8 | 64 位的浮点型 | 这两种浮点型数据格式遵循`IEEE 754`标准: + `float32` 的浮点数的最大范围约为 `3.4e38`,可以使用常量定义:`math.MaxFloat32`。 + `float64` 的浮点数的最大范围约为 `1.8e308`,可以使用一个常量定义:`math.MaxFloat64`。 **示例** ```go package main import ( "fmt" "math" "unsafe" ) //浮点型 func showFloat() { var num1 float32 = math.MaxFloat32 var num2 float64 = math.MaxFloat64 fmt.Printf("%f\n", math.Pi) fmt.Printf("%.2f\n", math.Pi) fmt.Printf("num1的类型是%T,num1是%g\n", num1, num1) fmt.Printf("num2的类型是%T,num1是%g\n", num2, num2) } func main() { showFloat() } ``` **运行结果** ``` 3.141593 3.14 num1的类型是float32,num1是3.4028235e+38 num2的类型是float64,num1是1.7976931348623157e+308 ``` 通过上面的程序,我们知道浮点数能表示的数值很大,但是浮点数的精度却没有那么大: - `float32` 的精度只能提供大约 `6` 个十进制数(表示小数点后 `6` 位)的精度。 - `float64` 的精度能提供大约 `15` 个十进制数(表示小数点后 `15` 位)的精度。 ### 三、布尔值 Go语言中以`bool`类型进行声明布尔型数据,布尔型数据只有`true(真)`和`false(假)`两个值。 如果你学过其他编程语言或许会发现,布尔型可以参与数值运算,也可以与其他类型进行转换。但是在 Go 中,真值是用 `true` 表示,并且 **不与** `1` 相等;同样的,假值是用 `false` 表示,并且 **不与** `0` 相等。 **注意**: + 布尔类型变量的默认值为false。 + Go 语言中不允许将整型强制转换为布尔型. + 布尔型无法参与数值运算,也无法与其他类型进行转换。 **示例** ```go func showBool(){ a := true b := false fmt.Println("a=", a) fmt.Println("b=", b) fmt.Println("true && false = ", a && b) fmt.Println("true || false = ", a || b) } ``` **运行结果** ``` a= true b= false true && false = false true || false = true ``` ### 四、复数型 复数型用于表示数学中的复数,如 `1+2j`、`1-2j`、`-1-2j` 等。在 Go 语言中提供了两种精度的复数类型:**`complex64`** 和 **`complex128`** ,分别对应 `float32` 和 `float64` 两种浮点数精度,如表所示。 | 类 型 | 字 节 数 | 说 明 | | ---------- | -------- | --------------------------------------------------- | | complex64 | 8 | 64 位的复数型,由 float32 类型的实部和虚部联合表示 | | complex128 | 16 | 128 位的复数型,由 float64 类型的实部和虚部联合表示 | **示例** ```go func showComplex() { // 内置的 complex 函数用于构建复数 var x complex64 = complex(1, 2) var y complex128 = complex(3, 4) var z complex128 = complex(5, 6) fmt.Println("x = ", x) fmt.Println("y = ", y) fmt.Println("z = ", z) // 内建的 real 和 imag 函数分别返回复数的实部和虚部 fmt.Println("real(x) = ", real(x)) fmt.Println("imag(x) = ", imag(x)) fmt.Println("y * z = ", y*z) } func main() { showComplex() } ``` **运行结果** ``` x = (1+2i) y = (3+4i) z = (5+6i) real(x) = 1 imag(x) = 2 y * z = (-9+38i) ``` 当然,我们可以对声明进行简化,使用自然的方式书写复数: ```go x := 1 + 2i y := 3 + 4i z := 5 + 6i ``` ### 五、字符串 Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64 等)一样。 Go 语言里的字符串的内部实现使用`UTF-8`编码。 **示例** ```go var bolg string // 定义名为str的字符串类型变量 bolg = "李林超博客" // 将变量赋值 bolg2 := "www.lilinchao.com" // 以自动推断方式初始化 ``` 有些字符串没有现成的文字代号,所以只能用转义字符来表示。常用的转义字符如表所示。 | 转 义 字 符 | 含 义 | | ----------- | ----------------------------------------- | | `\r` | 回车符 return,返回行首 | | `\n` | 换行符 new line, 直接跳到下一行的同列位置 | | `\t` | 制表符 TAB | | `\'` | 单引号 | | `\"` | 双引号 | | `\\` | 反斜杠 | 定义多行字符串的方法如下。 - 双引号书写字符串被称为字符串字面量(string literal),这种字面量不能跨行。 - 多行字符串需要使用反引号“`”,多用于内嵌源码和内嵌数据。 - 在反引号中的所有代码不会被编译器识别,而只是作为字符串的一部分。 **多行字符串** Go语言中要定义一个多行字符串时,就必须使用`反引号`字符: ```go s1 := `第一行 第二行 第三行 ` fmt.Println(s1) ``` 反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。 **字符串的常用操作** | 方法 | 介绍 | | :-----------------------------------: | :------------: | | `len(str)` | 求长度 | | `+`或`fmt.Sprintf` | 拼接字符串 | | `strings.Split` | 分割 | | `strings.contains` | 判断是否包含 | | `strings.HasPrefix,strings.HasSuffix` | 前缀/后缀判断 | | `strings.Index(),strings.LastIndex()` | 子串出现的位置 | | `strings.Join(a[]string, sep string)` | join操作 | **示例** ```go package main import ( "fmt" "strings" ) // 字符串常见操作 func main() { // 求字符串的长度 s1 := "hello" fmt.Println(len(s1)) s2 := "Leefs" fmt.Println(len(s2)) // 字符串拼接 fmt.Println(s1 + s2) s3 := fmt.Sprintf("%s - %s", s1, s2) fmt.Println(s3) // 字符串的分隔 s4 := "how do you do" fmt.Println(strings.Split(s4, "")) fmt.Printf("%T\n", strings.Split(s4, "")) // 判断是否包含 fmt.Println(strings.Contains(s4, "do")) // 前缀判断 fmt.Println(strings.HasPrefix(s4, "how")) // 后缀判断 fmt.Println(strings.HasSuffix(s4, "a")) // 判断子串的位置 fmt.Println(strings.Index(s4, "do")) // 最后子串出现的位置 fmt.Println(strings.LastIndex(s4, "do")) // Join操作 s5 := []string{"how", "do", "you", "do"} fmt.Println(s5) fmt.Println(strings.Join(s5, "+")) } ``` ### 六、字符 字符串中的每一个元素叫作“字符”,定义字符时使用单引号。Go 语言的字符有两种,如表所示。 | 类 型 | 字 节 数 | 说 明 | | ----- | -------- | ------------------------------------------------------------ | | byte | 1 | 表示 UTF-8 字符串的单个字节的值,表示的是 ASCII 码表中的一个字符,uint8 的别名类型 | | rune | 4 | 表示单个 unicode 字符,int32 的别名类型 | **示例** ```go package main import "fmt" func showChar() { var x byte = 65 var y uint8 = 65 fmt.Printf("x = %c\n", x) // x = A fmt.Printf("y = %c\n", y) // y = A } func sizeOfChar() { var x byte = 65 fmt.Printf("x = %c\n", x) fmt.Printf("x 占用 %d 个字节\n", unsafe.Sizeof(x)) var y rune = 'A' fmt.Printf("y = %c\n", y) fmt.Printf("y 占用 %d 个字节\n", unsafe.Sizeof(y)) } // 遍历字符串 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() } func main() { showChar() sizeOfChar() traversalString() } ``` **运行结果** ``` x = A y = A x = A x 占用 1 个字节 y = A y 占用 4 个字节 104(h) 101(e) 108(l) 108(l) 111(o) 44(,) 228(ä) 184(¸) 173() 229(å) 155() 189(½) 104(h) 101(e) 108(l) 108(l) 111(o) 44(,) 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语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。 强制类型转换的基本语法如下: ```go T(表达式) ``` 其中,T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等。 比如计算直角三角形的斜边长时使用math包的Sqrt()函数,该函数接收的是float64类型的参数,而变量a和b都是int类型的,这个时候就需要将a和b强制类型转换为float64类型。 ```go func sqrtDemo() { var a, b = 3, 4 var c int // math.Sqrt()接收的参数是float64类型,需要强制转换 c = int(math.Sqrt(float64(a*a + b*b))) fmt.Println(c) } ``` ### 八、fmt 格式输出 | **格式** | **含义** | | -------- | ------------------------------------------------------------ | | %% | 一个%字面量 | | %b | 一个二进制整数值(基数为 2),或者是一个(高级的)用科学计数法表示的指数为 2 的浮点数 | | %c | 字符型。可以把输入的数字按照 ASCII 码相应转换为对应的字符 | | %d | 一个十进制数值(基数为 10) | | %f | 以标准记数法表示的浮点数或者复数值 | | %o | 一个以八进制表示的数字(基数为 8) | | %p | 以十六进制(基数为 16)表示的一个值的地址,前缀为 0x,字母使用小写的 a-f 表示 | | %q | 使用 Go 语法以及必须时使用转义,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字 | | %s | 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符) | | %t | 以 true 或者 false 输出的布尔值 | | %T | 使用 Go 语法输出的值的类型 | | %x | 以十六进制表示的整型值(基数为十六),数字 a-f 使用小写表示 | | %X | 以十六进制表示的整型值(基数为十六),数字 A-F 使用小写表示 | *附参考文章链接* *http://www.go-edu.cn/2022/05/07/%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/* *https://www.liwenzhou.com/posts/Go/02_datatype/#autoid-1-4-0*
标签:
Golang基础
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2193.html
上一篇
03.Golang基础之变量与常量
下一篇
05.Golang容器之数组
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
递归
Linux
数据结构和算法
Docker
Tomcat
Sentinel
LeetCode刷题
Hbase
Hive
Stream流
人工智能
CentOS
数据结构
机器学习
Elastisearch
FastDFS
Spark Core
Java
Thymeleaf
Yarn
Kibana
ajax
Spring
线程池
Quartz
BurpSuite
正则表达式
Spark SQL
Http
SpringCloud
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭