基本数据类型
基本介绍
每一种数据都定义了明确的数据类型,不同的数据类型在内存中分配了不同大小的内存空间
整数类型
基本介绍
简单来说,就是存放整数数值的。例如:-2,-1,0,1,2,3等
基础小知识
bit (位)
- bit中文名称是位,音译“比特”,是用以描述电脑数据量的最小单位。
- 二进制数系统中,每个 0或1 就是一个位(bit)。
用途:数据率 就是数据的传输速率,单位是:比特/秒( 意思是每秒传送多少个二进制数字 1或0 )
byte (字节)
- 1字节=8位 (1 byte = 8 bits),byte就是常说的B(Byte),bit就是小b(bit)
- byte是数据存储的基础单位,1 byte为一个字节;一个字节(byte)可以表示256个数字(二进制数 0000 0000 - 1111 1111 即:0-255)。
扩展资料
最开始计算机只是处理数字运算,也就是0-9,加上运算符号,4bit足够了。用二进制 0000表示0,0001表示1,0010表示2,依次类推。
后来加入了字母、符号,数据处理扩充到8 bit,之后逐渐发展并诞生了ASCII编码标准,依据这一标准,将8bit表示出来的值使用一个新的单位来表示,这个新的单位被命名为字节(byte)。 所以1 byte等于8 bit是计算机发展中的一个以编码标准为依据约定出来的规则。
随着科技的发展,计算机需要处理的数据规模越来越大,原先的单位又不够用了,因此就有千位元组的单位 KB 出现,以下是换算关系:
1 Byte = 8 bits
1 KB = 1024 Bytes
1 MB = 1024 KB
1 GB = 1024 MB
整数的分类
1 byte = 8 bits,其中有一个bit用于做符号位,因此是27,而不是28
如下图 表示 1 个byte,即 8个bits(二进制)
符号位 | 数字位 | ||||||
---|---|---|---|---|---|---|---|
+或- | 0或1 | 0或1 | 0或1 | 0或1 | 0或1 | 0或1 | 0或1 |
如果符号位取正“+”,则二进制表示最大值是“+ 1 1 1 1 1 1 1”,最小值是“+ 0 0 0 0 0 0 0”
如果符号位取负“-”,则二进制表示最大值是“- 1 1 1 1 1 1 1”,最小值是“- 0 0 0 0 0 0 0”
符号位取负 “-” | |||||
---|---|---|---|---|---|
十进制 | -127 | -126 | …… | -1 | -0 |
二进制 | -1111111 | -1111110 | …… | -000001 | -0000000 |
符号位取正“+” | |||||
---|---|---|---|---|---|
十进制 | +0 | +1 | …… | +126 | +127 |
二进制 | +0000000 | +000001 | …… | +1111110 | +1111111 |
而“+ 0 0 0 0 0 0 0” 和 “- 0 0 0 0 0 0 0” 表示的都是0,所以约定把“- 0 0 0 0 0 0 0”的位置拿出来用来表示负数 -128
二进制 转为 十进制的特殊算法:
如果二进制正数全为 1,则十进制 = 2n-1,其中n表示二进制数中有多少个1,减 1 是因为要减去0号位
例如:
二进制“+ 1 1 1 1 1 1 1”,换成十进制为 27-1 = 127,即int8可以表示的最大正整数是 127
如果二进制负数全为 1,则十进制 = 2n,其中n表示二进制数中有多少个1,不用减 1 是因为没有-0号位,-0号位 被约定表示 -128
例如:
二进制“- 1 1 1 1 1 1 1”,换成十进制为 -27 = -128,即int8可以表示的最小负整数是 -128
类型 | 有无符号 | 占用内存空间 | 表示整数的范围 | 备注 |
---|---|---|---|---|
int | 有符号 | 32位系统 占用4字节 | -231 ~(231-1) | 32位系统中,int 等价于 int32 |
64位系统 占用8字节 | -263 ~(263-1) | 64位系统中,int 等价于 int64 | ||
int8 | 有符号 | 1字节 | -27 ~(27 -1) | -128 ~ 127 |
int16 | 有符号 | 2字节 | -215 ~(215-1) | -32768 ~ 32767 |
int32 | 有符号 | 4字节 | -231 ~(231-1) | -2147483648 ~ 2147483647 |
int64 | 有符号 | 8字节 | -263 ~(263-1) | -9223372036854775808 ~ 9223372036854775807 |
uint | 无符号 | 32位系统 占用4字节 | -231 ~(231-1) | |
64位系统 占用8字节 | -263 ~(263-1) | |||
uint8 | 无符号 | 1字节 | 0 ~(28-1) | 0 ~ 255 |
uint16 | 无符号 | 2字节 | 0 ~(216-1) | 0 ~ 65535 |
uint32 | 无符号 | 4字节 | 0 ~(232-1) | 0 ~ 4294967295 |
uint64 | 无符号 | 8字节 | 0 ~ (264-1) | 0 ~ 18446744073709551615 |
rune | 有符号 | 4字节 | -231 ~(231-1) | 等价于int32,表示一个unicode码(只可以表示一个汉字) |
byte | 无符号 | 1字节 | 0 ~(28-1) | 相当于uint8;当需要储存字符时,使用byte |
整数的使用说明
- Go中整数类型分为 有符号 和 无符号,int、uint 表示范围和系统有关(System 32/64 位)
- Go中整数默认声明的变量类型是int型
- Go中整数变量在使用时,遵守保小不保大原则,即在程序正确运行的前提下,尽量使用占用内存空间小的数据类型
- bit是计算机中的最小存储单位,byte是计算机中基本存储单元;1 Byte = 8bits
- 如下是查看变量的数据类型 和 占用字节大小的方法! ```go // 查看变量的数据类型 和 占用字节大小的方法! package main import ( “fmt” “unsafe” ) func main() { a := 100 fmt.Printf(“a 的变量类型是 %T\na 占用的字节是 %d\n”, a, unsafe.Sizeof(a)) // \n表示换行符 var b int64 = 100 fmt.Printf(“b 的变量类型是 %T\nb 占用的字节是 %d\n”, b, unsafe.Sizeof(b)) }
/ 代码运行结果展示 a 的变量类型是 int a 占用的字节是 8 b 的变量类型是 int64 b 占用的字节是 8 /
<a name="KQWsC"></a>
## 浮点数类型
<a name="vtdgW"></a>
### 基本介绍
浮点数类型 即 小数类型,用于存放小数,比如 -2.2 ,-1.1 ,1.1 ,2.2
<a name="Bh0Sr"></a>
### 浮点型的分类
| **分类** | **有无符号** | **占用内存空间** | **表示数的范围** | **备注** |
| --- | --- | --- | --- | --- |
| 单精度 float32 | 有符号 | 4字节 | -3.403E38~3.403E38 | -3.403 x 1038 ~ 3.403 x 1038 |
| 双精度 float64 | 有符号 | 8字节 | -1.798E308~1.798E308 | -1.798 x 10308 ~ 1.798 x 10308 |
<a name="FgEQs"></a>
### 浮点型的使用说明
- 浮点型在计算机中的存放形式:**浮点数 = 符号位 + 指数位 + 尾数位,**尾数位指小数点后的数字
- **尾数部分可能丢失,造成精度损失(保存高精度数,须使用float64)**
```go
// 演示浮点型尾数部分可能丢失,造成精度损失,且编译器不会报错提示
package main
import (
"fmt"
)
func main (){
var a float32 = -1234.56789012345
var b float64 = -1234.56789012345
fmt.Println("a = ", a)
fmt.Println("b = ", b)
}
/*
代码运行结果展示
a = -1234.5679
b = -1234.56789012345
通过对比a、b打印的值可以看出,float32类型的变量a尾数部分丢失了6位,造成了精度损失
说明:
1、float64 比 float32 精度高;
2、如果需要保存一个高精度的数,应该选择使用float64
*/
- 占用相同字节大小的情况下,浮点数比整数可以表示的范围更大
- 浮点型的默认声明的变量类型是float64类型 ```go // 演示展示浮点型默认声明的变量数据类型是float64 package main import ( “fmt” ) func main () { a := 3.14 fmt.Printf(“a的数据类型是%T \n”, a) }
/ 代码运行结果展示 a的数据类型是float64 /
- 通常情况下,开发过程中**推荐使用float64**,因为它比float32精度更高、更准确
- 浮点型常量有两种表示方式:**十进制 **和** 科学计数法**
| **浮点数** | **十进制** | **科学计数法** | **备注** |
| --- | --- | --- | --- |
| 512.3 | 512.3 | 5.123E2 | 5.123 x 102 |
| 0.05123 | 0.05123 | 5.123E-2 | 5.123 x 10-2 |
<a name="T9TGh"></a>
## 字符类型
<a name="OTpbh"></a>
### 基本介绍
- **Go中没有专门的字符类型,如果要存储单个字符/字母,一般用byte来保存,使用单引号括起来**
**(汉字不能使用 byte 保存,会报错overflow,因为 byte 只占用 1 个字节,范围是0-255,因此只能表示ASCII编码在0-255范围内的字符)**
- 字符串就是一串固定长度的字符连接起来的字符序列,Go中字符串是由单个字节连接起来的
也就是说,**对于传统的字符串是由字符组成,而Go中字符串不同,是由字节组成**
- **打印字符,显示的是该字符在ASCII码表中对应的十进制编号**
[ASCII编码在线查询](https://www.qqxiuzi.cn/bianma/ascii.htm)
```go
package main
import (
"fmt"
)
func main(){
// 注意byte只能存储一个字符/字母,且须使用单引号括起来
var a byte = 'A' // 注意须使用单引号,如果是string类型,则使用双引号括起来
fmt.Println("a =", a)
var b byte = '0' // 注意须使用单引号,如果是string类型,则使用双引号括起来
fmt.Println("b =", b)
var c byte = '#' // 注意须使用单引号,如果是string类型,则使用双引号括起来
fmt.Println("c =", c)
}
字符的使用说明
- 如果需要保存的字符在ASCII码表范围内,比如[0-9,a-z,A-Z…],可以直接以 byte 类型保存
- 如果需要保存的字符对应码值大于255,这时我们可以考虑使用 int 类型保存
如果我们需要按照字符的方式打印输出,这时我们需要使用格式化输出,例:fmt.Printf(“%c”, a)
package main
import (
"fmt"
)
func main(){
var a int = '申' // 注意此处须使用单引号
fmt.Println("a =", a)
fmt.Printf("a = %c \n", a)
}
Go中字符常量是用单引号扩起来的单个字符;
例如:var a int = ‘风’ ; var b byte = ‘S’ ; var c byte = ‘9’;
- Go中允许使用转义字符 \ 将其后的字符转变为特殊字符型常量;
例如:var d char = ‘\n’
- Go中字符使用UTF-8编码,查询字符对应的UTF-8编码
- UTF-8是编码规则,Unicode是字符集;UTF-8是Unicode是实现方式
- 在Go中,字符的本质是一个整数,直接打印输出的是该字符对应的UTF-8编码的码值 ```go // 演示字符的本质是一个整数 package main import ( “fmt” ) func main (){ var a byte = ‘S’ fmt.Println(“a =”, a) }
/ 代码运行结果展示 a = 83 /
- **可以直接给某个变量赋值一个十进制数字,然后格式化打印输出%c,会输出该十进制数字对应的Unicode字符**
```go
// 演示打印十进制数字对应的Unicode字符
package main
import (
"fmt"
)
func main () {
var a = 30003
fmt.Printf("十进制数字 30003 对应的Unicode字符是 %c \n", a)
}
/*
代码运行结果展示
十进制数字 30003 对应的Unicode字符是 申
*/
- 字符型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码值 ```go // 演示字符型运算 package main import ( “fmt” ) func main (){ var a = 24 + ‘s’ fmt.Println(“a =”, a) }
/ 代码运行结果展示 实际的运算过程是24 + 字符s的Unicode编码值125 即a = 24 + 125 a = 139 /
<a name="OVhs9"></a>
### 字符型本质说明
- 字符型存储到计算机中,需要将字符对应的十进制码值(整数)找出来
- 存储:字符 -> 对应十进制码值 -> 换算成二进制 -> 进行存储
- 读取:二进制 -> 换算成十进制码值 -> 对应字符 -> 进行读取
- 字符和码值的对应关系是通过字符编码决定的(是预先规定好的)
- Go语言的统一编码是UTF-8
<a name="LhuuS"></a>
## 布尔型bool
<a name="oq4BN"></a>
### 基本使用
- 布尔类型即 bool 类型,bool类型只允许取值 true 或 false
- bool 类型默认取值 是 false
```go
// 演示Go中 bool 类型的默认取值
package main
import (
"fmt"
)
func main (){
var a bool
fmt.Println("a =", a)
}
/*
代码运行结果演示
a = false
*/
bool 类型占用 1 字节 ```go // 演示Go中 bool 类型的使用 和 占用字节数 package main import ( “fmt” “unsafe” ) func main (){ var a bool = true fmt.Println(“a =”, a) fmt.Println(“a 占用的字节数 =”, unsafe.Sizeof(a))
var b bool = false fmt.Println(“b =”, b) fmt.Println(“b 占用的字节数 =”, unsafe.Sizeof(b)) }
/ 代码运行结果展示 a = true a 占用的字节数 = 1 b = false b 占用的字节数 = 1 /
- bool 类型适用于逻辑运行,一般用于程序流程控制
<a name="ZkTrk"></a>
## 字符串类型
<a name="mB2iL"></a>
### 基本介绍
- 字符串就是一串固定长度的字符连接起来的字符序列。
- Go语言的字符串是由单个字节连接起来的
- Go语言的字符串的字节使用UTF-8编码来标识Unicode
<a name="54f0j"></a>
### 基本使用
```go
// 演示字符串string 类型的基本使用
package main
import (
"fmt"
)
func main (){
var a string = "I am Chinese!"
fmt.Println(a)
}
双引号与反引号
- 双引号“” 会识别并激活转义字符
- 反引号 `` 以字符串的原生格式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
``go // 演示字符串 双引号、反引号的基本使用 package main import ( "fmt" ) func main () { a := "fh\nbm" b :=
fh\nbm` fmt.Println(“a =”, a) fmt.Println(“b =”, b) }
/ 代码运行结果展示 a = fh bm b = fh\nbm /
<a name="Q9S0H"></a>
### 字符串拼接
```go
// 演示字符串string 拼接的基本使用
package main
import (
"fmt"
)
func main () {
a := "I " + "Love "
a += "You" // += 相当于 a = a + "You"
fmt.Println("a =", a)
}
/*
代码运行结果展示
a = I Love You
*/
长字符串拼接
当字符串太长,一行无法美观的展示时,可以分行书写,但是需要将 加号+ 放在上一行末尾
// 演示长字符串拼接,多行书写
package main
import (
"fmt"
)
func main () {
a := "Hi,beauty, " + "fall in love with me, " +
"I like you, " + "love you!"
fmt.Println(a)
}
/*
代码运行结果展示
Hi,beauty, fall in love with me, I like you, love you!
*/
注意事项
- 字符串string 一旦赋值后,就不能再更改(Go中字符串是不可变的)
基本数据类型的默认值
基本介绍
在Go中,每个数据类型的变量都有一个默认值,当程序没有进行赋值时,就会保留默认值,在Go中,默认值又称为零值
默认值
数据类型 | 默认值 |
---|---|
整数 int | 0 |
浮点数 float | 0 |
布尔值 bool | false |
字符串 string | 空 |
默认值验证:
// 演示验证基本数据类型的默认值
package main
import (
"fmt"
)
func main () {
var a int
var b float64
var c bool
var d string
fmt.Println("a =", a)
fmt.Println("b =", b)
fmt.Println("c =", c)
fmt.Println("d =", d)
}
/*
代码运行结果展示
a = 0
b = 0
c = false
d =
*/
基本数据类型-值类型之间相互转换
基本介绍
与JAVA、C不同的是,GoLang中数据类型不能自动切换,Go在不同数据数据类型的变量之间赋值时,需要先进行数据类型转换
基本语法
表达式:T(v)
说明:T是需要转换的目的变量,v是待转换的源变量
// 演示基本数据类型之间相互转换
package main
import (
"fmt"
)
func main () {
var a int8 = 24
var b int16 = int16(a)
var c float64 = float64(a)
fmt.Printf("a = %v b = %v c = %v \n", a, b, c)
}
/*
代码运行结果展示
a = 24 b = 24 c = 24
*/
注意事项
- GO中,数据类型的转换可以从 表示范围小的 -> 表示范围大的,也可以从 表示范围大的 -> 表示范围小的
- 被转换的知识变量的值,变量本身的数据类型并没有发生变化
- 在转换时,将一个 int64 范围内的大值 转成 int8 ,编译的时候不会报错,但是运行结果与预期不一样,
因此在进行基本数据类型转换时,需要考虑每个数据类型可以表示的范围
// 演示基本数据类型转换 overflow
package main
import (
"fmt"
)
func main () {
var a int16 = 129
var b int8 = int8(a)
fmt.Println("b =", b)
}
/*
代码运行结果展示
b = -127
b 的预期值应该是 129, 但是运行结果为 -127, 是因为按照溢出处理了
*/
基本数据类型与string相互转换
基本介绍
在程序开发中,我们经常需要将基本数据类型转成string,或者将string转换成基本数据类型
基本数据类型 转 string
方法一:fmt.Sprintf(“%参数”, 表达式)
参数 和 表达式 的数据类型须相匹配,fmt.Sprintf() 会返回转换后的字符串
// 演示基本数据类型 转 string, 方法一:fmt.Sprintf
package main
import (
"fmt"
)
func main() {
var a int8 = 24
var b float64 = 3.14
var c bool = true
var d byte = 'S'
var e1 string = fmt.Sprintf("%d", a)
fmt.Printf("e1 的数据类型是%T e1 = %v\n", e1, e1)
var e2 string = fmt.Sprintf("%f", b)
fmt.Printf("e2 的数据类型是%T e2 = %v\n", e2, e2)
var e3 string = fmt.Sprintf("%t", c)
fmt.Printf("e3 的数据类型是%T e3 = %v\n", e3, e3)
var e4 string = fmt.Sprintf("%c", d)
fmt.Printf("e4 的数据类型是%T e4 = %v\n", e4, e4)
}
/*
代码运行结果展示
e1 的数据类型是string e1 = 24
e2 的数据类型是string e2 = 3.140000
e3 的数据类型是string e3 = true
e4 的数据类型是string e4 = S
*/
方法二:使用 strconv 函数
// 演示基本数据类型 转 string, 方法二:使用 strconv 函数
package main
import (
"fmt"
"strconv"
)
func main () {
/*
FormatInt(i int64, base int)
i int64 表示须传入 int64 类型的变量
base int 表示需要输出的是什么进制的数字(范围是 2 - 36, 此处我们填 10,表示输出十进制数字)
*/
var a int8 = 24
var e1 = strconv.FormatInt(int64(a), 10)
fmt.Printf("e1 的数据类型是%T e1 = %v\n", e1, e1)
/*
FormatFloat(f float64, fmt byte, prec, bitSize int)
f float64 表示须传入 float64 类型的变量
fmt byte 表示需要输出的格式
prec 表示精度,即保留小数点后多少位
bitSize int 表示待传入的变量是什么数据类型,即变量转换前的源数据类型
*/
var b float64 = 3.14
var e2 = strconv.FormatFloat(b, 'f', 10, 64)
fmt.Printf("e2 的数据类型是%T e2 = %v\n", e2, e2)
/*
FormatBool(b bool)
b bool 表示须传入 bool 类型的变量
*/
var c bool = true
var e3 = strconv.FormatBool(c)
fmt.Printf("e3 的数据类型是%T e3 = %v\n", e3, e3)
}
/*
代码运行结果展示
e1 的数据类型是string e1 = 24
e2 的数据类型是string e2 = 3.1400000000
e3 的数据类型是string e3 = true
*/
string 转 基本数据类型
使用 strconv 函数
// 演示 string 转 基本数据类型
package main
import (
"fmt"
"strconv"
)
func main() {
/*
a, _ = strconv.ParseBool(str string)
因为使用 strconv.Parse* 会返回两个值,一个是转换后的变量值,一个是err error
但是我们只需要转换后的变量值,所以使用 _ 将第二个返回值置空
*/
var str1 string = "true"
var a bool
a, _ = strconv.ParseBool(str1)
fmt.Printf("a 的数据类型是%T a = %v\n", a, a)
/*
b, _ = strconv.ParseInt(s string, base int, bitSize int)
base int 表示需要输出的是什么进制的数字(范围是 2 - 36, 此处我们填 10,表示输出十进制数字)
bitSize int 表示需要输出的是什么数据类型(表示范围须匹配,不能溢出),0、8、16、32、64 分别代表 int、int8、int16、int32、int64
*/
var str2 string = "12345678"
var b int64
b, _ = strconv.ParseInt(str2, 10, 64)
fmt.Printf("b 的数据类型是%T b = %v\n", b, b)
/*
c, _ = strconv.ParseFloat(s string, bitSize int)
bitSize int 表示需要输出的是什么数据类型(表示范围须匹配,不能溢出),32、64分别代表float32、float64
*/
var str3 string = "3.14"
var c float64
c, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("c 的数据类型是%T c = %v\n",c, c)
}
注释事项
在将 string 转成 基本数据类型 时,须确保 string 的值和目标基本数据类型是匹配的,比如我们可以将“123” 转成整数类型,但是无法把“helloworld”转成整数类型,如果强制进行转换,Golang会直接将其转成0