分类
Go语言中的数据类型分为:基本数据类型和复合数据类型
- 基本数据类型
整型、浮点型、布尔型、字符串
- 复合数据类型
数组、切片、结构体、函数、map、通道(channel)、接口等
整型
整型分为以下两个大类:
- 有符号整型按长度分:int8、int16、int32、int64
- 对应的无符号整型:uint8、uint16、uint32、uint64
- 定义int类型
默认值为空
var num int = 10
fmt.Printf("num=%v 类型:%T",num, num)
//num=10 类型:int
默认的int类型长度跟随操作系统32/64位而变化
类型 | 范围 | 占用空间 |
---|---|---|
int8 | -127~128 | 1B |
int16 | -32768~32767 | 2B |
int32 | -231~231-1 | 4B |
int64 | -263~263-1 | 8B |
- 不同长度的int之间的转换
var a1 int32 = 10
var a2 int64 = 21
fmt.Println(a1 + a2)
//报错,int32和int64为不同类型,不能直接参与运算
fmt.Println(int64(a1) + a2)
高位向底位转换时是直接截取,要注意数值符号
byte和rune类型
- uint8类型,或者叫byte型,代表了ASCII的一个字符
- rune类型,代表一个UTF-8字符。当需要处理中文、日文或其他复合字符时,需要用到rune类型。rune类型实际是一个int32
var a = 'a'
fmt.Printf("值:%v 类型:%T")
//值:97 类型:int32
fmt.Printf("值:%v 类型:%T")
//值:a 类型:int32
在Go中一个字母占用1个字节,一个汉字占用3个字节(utf-8编码)
var str = "this"
fmt.Println(unsafe.Sizeof(str), len(str))
//16 4
这里不管
str
的内容是多少,Sizeof
始终打印16
,与他的内存结构有关;要查看他真实长度的时候,可以用len()
方法
Sizeof
查看不同的数据类型,在内存中占用的存储空间(无法查看string类型)
var num int8 = 15
fmt.Println(unsafe.Sizeof(num))
//1
浮点型(与C基本相同)
Go支持两种浮点数:float32和float64,四舍五入保留6位小数,分别占用4B和8B
var num float32 = 3.12
fmt.Println(unsafe.Sizeof(num))//4
var c float64 = 3.14159255
fmt.Printf("%v-%f", c, c)
//3.14159255-3.141592
fmt.Printf("%.2f")
//保留两位小数3.14
Go语言中默认浮点数为float64
- 科学计数法表示浮点类型
3.14e 表示3.14*102
- float精度丢失问题
几乎所有的编程语言都有精度丢失的问题,这是典型的二进制浮点数精度损失问题。在定长条件下,二进制小数和十进制小数互转可能有精度丢失。
var num float64 = 1129.6
fmt.Println(num*100)
//112529.9999999999
可以使用第三方包来解决精度损失问题
https://github.com/shopspring/decimal
import(
"fmt"
"github.com/shopspring/decimal"
)
func main(){
m1 := 8.2
m2 := 3.8
res := decimal.NewFromFloat(m1).Sub(decimal.NewFromFloat(m2))
fmt.Println(res)
}
- int与float之间的转换
int => float
a := 10
b := float64(a)
fmt.Printf("a的类型是%T,b的类型是%T", a, b)
//a的类型是int,b的类型是float
var a1 float32 = 23.4
a2 := float64(a1)
//a1是float32,a2是float64
float => int会直接截取,丢失数据(不建议)
布尔型数据
- 布尔型变量默认为false
- Go语言中不允许将整型强制转换为布尔型
- 布尔型无法参与数值运算,也无法与其他类型转换
字符串
默认值为空,用双引号
""
包裹值
- 字符串转义字符
转义符 | 含义 |
---|---|
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
- 多行字符串(JS中ES6的模板字符串)
str := `this
is
str
`
fmt.Println(str)
- 字符串的常用操作
方法 | 说明 |
---|---|
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix, strings, HasSuffix | 前缀/后缀判断 |
strings.Index(), strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | 切片转字符串 |
var str1 = "aaa"
var str2 = "哈喽"
var str3 = "123-456-789"
fmt.Println(len(str1), len(str2))//4 6
fmt.Sprintf("%v %v", str1, str2)//aaa 哈喽
arr := strings.Split(str,"-")
fmt.Println(arr)//切片[123 456 789]
fmt.Println(strings.Join(arr, "-"))//123-456-789
newArr := []string{"php","JavaScript","golang"}
fmt.Pringln(string.Join(newArr))//[php JavaScript golang]
str10 := "this is str"
str11 := "this"
flag := strings.Contains(str10, str11)
//判断str10中是否包含true
fmt.Println("strings.HasPrefix(str10, str11)")//判断str1是否以str2开头
fmt.Println("strings.HasSuffix(str10, str11)")//判断str2是否以str2结尾
fmt.Println(strings.Index(str10, str11))
//判断str11在str10中首次出现的位置 0
fmt.Println(strings.LastIndex(str10, "is"))
//判断str11在str10中最后出现的位置(位置始终按照从左往右计算)5
- 循环遍历字符串
s := "hello"
for i :=0; i < len(s); i++ {//byte
fmt.Printf("%v(%c)", s[i], s[i])
}
fmt.Println()
//打印有问题,因为一个汉字占用了3个字节
for _,r := range s {//rune
fmt.Printf("%v(%c)", r, r)
}
- 修改字符串
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
s1 := "big"
byteS1 := []byte(s1)
byteS1[0] = "p"
fmt.Println(string(byteS1))//pig
s2 := "胡萝卜"
runeS2 := []rune(s2)
runeS2[0] = '白'
fmt.Println(string(runeS2))//白萝卜
- sprintf
string=>other. sprintf使用中需要注意转换的格式
int为%d float为%f bool为%t byte为%c
var i int = 20
var f float64 = 12.456
var t tool = true
var b byte = 'a'
str := fmt.Sprintf("%d", i)
fmt.Printf("%v%T", str, str)//20string
str2 := fmt.Sprintf("%.2f", f)
fmt.Printf("%v%T", str2, str2)//12.46string
str3 := fmt.Sprintf("t", f)
fmt.Printf("%v %T", str3, str3)//true string
str4 := fmt.Sprintf("%c", b)
fmt.Printf("%v %T")//a string
- ParseInt(string数据,进制,位数)
ParseInt方法有两个返回值,一个是转换的结果,一个是返回的错误信息
str := "123456"
fmt.Printf("%v%T\n", str, str)
num, _ := strconv.ParseInt(str, 10, 64)
fmt.Printf("%v%T",num, num)//123456 int64
- ParseFloat(string数据,位数)
str := 123.456
num, _ := strconv.ParseFloat(str, 64)//123.456 float64
- strconv包
其他类型转string类型
1.int=>string: 该方法中接收两个参数,参数1:int64的数值;参数2:当前int类型的进制
var i int = 20
str1 := strconv.FormatInt(int64(i), 10)
fmt.Printf("%v%T", str1, str1)//20string
var f float = 20.32
str2 := strconf.FormatFloat
- float=>string: 接收四个参数
参数1:传入的值;
参数2:格式化的方式 'f'(-ddd.dddd)……;
参数3:保留的小数点(-1表示不对小数点格式化);
参数4:格式化的类型(传入64/32)
var f float32 = 3.141592
str := strconv.FormatFloat(float64(f), 'f', 4, 64)
fmt.Printf("%v%T", str, str)//3.1416 string
- bool=>string
str := strconv.FormatBool(true)
fmt.Printf("%v%T", str, str)//true string
数值型无法和bool类型转换
- 字符=>string
a := 'b'
str := strconv.FormatUint(uint64(a), 10)
fmt.Printf("%v%T", str, str)//98 string
自定义类型和类型别名
//自定义类型
type myInt int
//类型别名
type myFloat = float64
func main(){
var a myInt = 10
fmt.Printf("%v %T", a, a) //10 main.myInt
var b myFloat = 123.4
fmt.Printf("%v %T", b, b) //123.4 float64
}
有疑问加站长微信联系(非本文作者)