首先贴出来Go语言官方文档的类型章节,方便随时查阅。
对比PHP语言,Go语言中数据类型就比较丰富了,除了整型、浮点型、布尔型、字符串、数组外,还有切片、结构体、函数、map、通道(channel)等。
go语言的数据类型可以分为2个大类:
基础数据类型:布尔(bool),数值(整型、浮点),字符串(string)
复合数据类型:数组(array),切片(slice),结构体(struct)、函数(function)、集合(map)、通道(channel)、指针(pointer)、接口(interface)
基础数据类型
布尔类型
默认值:false
布尔类型就没有什么好说的了,跟其他语言也都一样,只能是常量true和false。
与PHP不一样的是,Go语言中布尔类型比较孤立,不能与其他类型转换,比如不能把布尔类型转换成整型0和1,也不能将整型转换成布尔,既然不能转换成整型,那很自然也就不能参与数值运算了,比如+,-等等。
数值类型
整型
整型可以分为两个大类:有符号位和无符号位,有符号位对应的是int8、int16、int32、int64,无符号位对应的是uint8、uint16、uint32、uint64。
int、uint 是基于架构的,如果我们的架构是32位的,int的长度就相当于int32,uint同理。
uintptr是用于存放指针的,但是从数据类型来说是属于整型,即使uintptr类型的变量仍然有效,由uintptr类型的变量表示的指针地址的数据也可能被GC回收。
所以我们选择整型数据类型时,根据需要存储的数值长度和有符号无符号来选择就好了。
Go语言中无法直接定义二进制数,但是可以定义八进制和十六进制的数。
注意看下面的代码,定义八进制和十六进制实际上也是整型。
我们在代码里面通常不会用到这些八进制、十六进制的数,一般就给文件定义权限会用到八进制的数,十六进制的数是涉及到内存地址的时候。
package main
import "fmt"
func main() {
// 十进制
var i1 int = 10
// 八进制 以0开头
var i2 int = 012
// 十六进制 以0x开头
var i3 int = 0xa
fmt.Printf("十进制数10转换-- 十进制:%d,八进制:%o,十六进制:%x\n",i1,i1,i1)
fmt.Printf("八进制数012转换-- 十进制:%d,八进制:%o,十六进制:%x\n",i2,i2,i2)
fmt.Printf("十六进制0xa转换-- 十进制:%d,八进制:%o,十六进制:%x\n",i3,i3,i3)
}
D:\go\src\day01>go run main.go
十进制数10转换-- 十进制:10,八进制:12,十六进制:a
八进制数012转换-- 十进制:10,八进制:12,十六进制:a
十六进制0xa转换-- 十进制:10,八进制:12,十六进制:a
浮点
Go语言中浮点类型有
float32
和float64
,区别是最大值不一样,
通过类型推导
定义变量时,如f := 1.1
,默认是float64
类型。
还有个复数complex64
和complex128
类型也属于浮点类型,但代码中不常见,一般是做科学计算用的,暂时不需要过多了解。
字符串
Go语言中的字符串内部实现使用
UTF-8
编码,可以使用双引号""和反引号``定义值的内容。
区别是双引号中可以使用转义符“\”反斜线,而反引号不支持转义符。可以暂时理解为反引号就相当于PHP中的单引号。
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
// 双引号定义字符串:其中有"\t"制表符“需要转义,并且有“\n”换行符
s1 := "\t黄翠刚\n你好!"
// 反引号定义字符串:演示一下反引号不会转义字符
s2 := `\t黄翠刚\n你好!`
// 反引号定义字符串:演示一下与s1变量一样的字符串
s3 := ` 黄翠刚
你好!`
fmt.Printf("这是s1变量的值:\n%v\n这是s2变量的值:\n%v\n这是s3变量的值:\n%v\n",s1,s2,s3)
// 字符串相关操作
// 从字符串中提取所有的中文
ss := regexp.MustCompile("[\u4e00-\u9fa5]").FindAllStringSubmatch(s1, -1)
fmt.Printf("从字符串中提取所有的中文:%#v\n", ss)
fmt.Println("从字符串中提取所有的中文统计字数:",len(ss))
// 获取字符串的长度
fmt.Println(len(s1))
// 字符串拼接
s4 := "黄翠刚"
s5 := "你好!"
s6 := s5 + s4
fmt.Println(s6)
// 字符串拼接
// (fmt包Print系列的方法是输出到终端,而Sprint系列的方法是返回值,
// 简单字符串拼接可以使用"+"加号,复杂格式化的字符串拼接建议用fmt包Print系列的方法)
s7 := fmt.Sprintf("%v%v",s5,s4)
fmt.Println(s7)
// 字符串分割
// (fmt包的Split系列方法是用于处理字符串分割的,返回[]string,
// 我们定义的s8字符串当中实际是有\n换行符的,所以分割出来的结果是一行一行的字符串)
s8 := `今天天气真好!
但是我昨晚没有睡好,今天状态不佳!`
s9 := strings.Split(s8,`\n`)
fmt.Printf("%T,%v\n",s9,s9)
// 字符串拼接
// s9是s8拆分出来的,我们这里又使用相同的字符串拼接,实际上拼接出来的字符串就是与s8拆分前的原始字符串相同了
s10 := strings.Join(s9,`\n`)
fmt.Println(s10)
// 判断字符串中是否存在指定的字符,返回true|false 此处为true
fmt.Println(strings.Contains(s8,`!`))
// 判断字符串前缀是否匹配,返回true|false 此处为true
fmt.Println(strings.HasPrefix(s8,`今天`))
// 判断字符串后缀是否匹配,返回true|false 此处为false
fmt.Println(strings.HasSuffix(s8,`状态不佳`))
// 获取字符串首次出现的索引位置
fmt.Println(strings.Index(s8, `气`))
// 获取字符串最后一次出现的索引位置
fmt.Println(strings.LastIndex(s8, `今`))
}
D:\go\src\day01>go run main.go
这是s1变量的值:
黄翠刚
你好!
这是s2变量的值:
\t黄翠刚\n你好!
这是s3变量的值:
黄翠刚
你好!
从字符串中提取所有的中文:[][]string{[]string{"黄"}, []string{"翠"}, []string{"刚"}, []string{"你"}, []string{"好"}}
从字符串中提取所有的中文统计字数: 5
20
你好!黄翠刚
你好!黄翠刚
[]string,[今天天气真好!
但是我昨晚没有睡好,今天状态不佳!]
今天天气真好!
但是我昨晚没有睡好,今天状态不佳!
true
true
false
9
48