【Go语言】基础数据类型
一、数据类型
基础数据类型
类型 | 长度(字节) | 默认值 | 说明 |
bool | 1 | false | |
byte | 1 | 0 | uint8,取值范围 [0,255] |
rune | 4 | 0 | Unicode,等价于 int32 |
int,uint | 4或8 | 0 | 32位 或 64位,取决于操作系统 |
int8,uint8 | 1 | 0 | [-128,127] [0,255] |
int16,uint16 | 2 | 0 | [-32768,32767] [0,65535] |
int32,uint32 | 4 | 0 | [-21亿,21亿] [0,42亿] |
int64,uint64 | 8 | 0 | |
float32 | 4 | 0.000000 | |
float64 | 8 | 0.000000 | |
complex64 | 8 | real float32 + imag float32 | |
complex128 | 16 | real float64 + imag float64 | |
uintptr | 4或8 | 以存储指针的uint32 或 uint64 整数 |
复合数据类型
类型 | 默认值 | 说明 |
array | 数组,值类型 | |
struct | 结构体,值类型 | |
string | "" | 字符串,UTF8 字符串 |
slice | nil | 动态数组,引用类型 |
map | nil | hash表,键值对,引用类型 |
channel | nil | 管道,引用类型 |
interface | nil | 接口 |
function | nil | 函数 |
二、自定义类型
类型别名
// 内置的自定义类型别名 type byte = uint8 type rune = int32
自定义类型
// 自定义一个uint8类型,命名为 signal type signal uint8 // 自定义一个map类型,命名为ms type ms map[string]string //自定义一个函数类型,命名为add type add func(a,b int)int //自定义一个结构体,命名为user type User struct { Name string Age uint8 } func (self User) Who() { fmt.Printf("My Name is %s, age is %d\n", self.Name, self.Age) } var stu User func main() { stu.Name = "tom" stu.Age = 18 stu.Who() } PS F:\go\go_project\test> go run .\data_type\costom.go My Name is tom, age is 18
三、字符串
字符串赋值
字符串可以通过 "" (双引号)或者 ·· (反引号)进行赋值
双引号赋值支持 转义字符 使用,反引号赋值不支持 字符
范例:
func main() { // 支持Unicode所有字符格式 var str1 = "My Name is 邱志成√" // “” 内使用转义字符 var str2 = "Say: \" Hello!\tWorld!\" on C:\\Windows\\User\n" // `` 内无需使用转义,完整输出段落内容,包括换行、空格及制表符 var str3 = `My Name is 邱志成√ Say: "Hello World!" HomeDir C:\Windows\User` fmt.Println(str1) fmt.Println(str2) fmt.Println(str3) }
输出结果:
字符串常用操作
方法 介绍 输出结果类型 len(str) 字符长度(默认是字节长度) int strings.Split 分割 []string strings.Contains 判断是否包含 bool strings,HasPrefix
strings.HasSuffix前缀判断
后缀判断bool strings.Index()
strings.LastIndex()子串出现位置
全部位置
最后一次出现的位置int 范例:
func method_string() { str := "自我介绍 My first name is Janzen, and my last name is Qiu, I'm 27 years old." r_str := []rune(str) fmt.Printf("str is %s\n", str) fmt.Printf("str字符长度:len = %d(%T)\n", len(str), len(str)) fmt.Printf("r_str字符长度:len = %d(%T)\n", len(r_str), len(r_str)) str_spl := strings.Split(str, " ") fmt.Printf("str以空格分割结果:strings.Split = %v(%T)\n", str_spl, str_spl) fmt.Printf("str以空格分割长度:len = %d(%T)\n", len(str_spl), len(str_spl)) str_con := strings.Contains(str, "name") fmt.Printf("str包含'name' = %t(%T)\n", str_con, str_con) str_HasP := strings.HasPrefix(str, "自我介绍") fmt.Printf("str以'自我介绍'开头 = %t(%T)\n", str_HasP, str_HasP) str_HasS := strings.HasSuffix(str, ".") fmt.Printf("str以'.'结尾 = %t(%T)\n", str_HasS, str_HasS) str_sel := "name" str_Index := strings.Index(str, str_sel) str_LastIndex := strings.LastIndex(str, str_sel) fmt.Printf("str出现'%s'的位置%v(%T), 最后一次出现在%v(%T)\n", str_sel, str_Index, str_Index, str_LastIndex, str_LastIndex) { str_sel := "named" str_Index := strings.Index(str, str_sel) str_LastIndex := strings.LastIndex(str, str_sel) fmt.Printf("str出现'%s'的位置%v(%T), 最后一次出现在%v(%T)\n", str_sel, str_Index, str_Index, str_LastIndex, str_LastIndex) } }
输出结果:
字符串拼接
- 通过 + 连接
- func fmt.Sprintf(format string, a ... interface{}) string
- func strings.Join(elems []string, sep string) string
- 当有大量的strring需要拼接时,用 strings.Builder 效率更高
范例:
func join_strings() { str1 := "My Name" str2 := "is" str3 := "Janzen" fmt.Printf("str1 = '%s', str2 = '%s', str3 = '%s'\n", str1, str2, str3) // 使用 + 进行字符连接 s0 := str1 + " " + str2 + " " + str3 fmt.Printf("s0 = %s\n", s0) // 使用 fmt.Sprintf 进行字符连接 s1 := fmt.Sprintf("%s %s %s", str1, str2, str3) fmt.Printf("s1 = %s\n", s1) // 使用 func strings.Join 进行字符连接 s2 := strings.Join([]string{str1, str2, str3}, "_") fmt.Printf("s2 = %s\n", s2) // 使用 strings.Builder 进行字符连接 sb := strings.Builder{} sb.WriteString(str1) sb.WriteString(" ") sb.WriteString(str2) sb.WriteString(" ") sb.WriteString(str3) s3 := sb.String() fmt.Printf("s3 = %s\n", s3) }
输出结果:
byte 和 rune
- string中的每个元素叫“字符”,字符有两种格式:
- byte:1个字节,代表 ASCII码 中的一个字符,一个字符可能存在占用多个byte
- rune:4个字节,代表 UTF-8 编码的一个字符,一个汉字可用一个rune表示
- string 底层是一个byte数组,string的长度就是该byte数组的长度,UTF-8编码下的一个汉字占用3个byte,即一个汉字占用3个长度
- string 可以转换为 []byte h或 []rune 类型
- string 是常量,不能修改其中字符
范例:
func rune_byte_strings() { str := "My Name is 邱志成©" b_str := []byte(str) r_str := []rune(str) for i := 0; i < len(str); i++ { fmt.Printf("%x '%s'\t", str[i], string(str[i])) } fmt.Printf("\nstr len = %d\n\n", len(str)) for _, bs := range b_str { fmt.Printf("%x '%s'\t", bs, string(bs)) } fmt.Printf("\nb_str len = %d\n\n", len(b_str)) for _, rs := range r_str { fmt.Printf("%x '%s'\t", rs, string(rs)) } fmt.Printf("\nr_str len = %d\n\n", len(r_str)) }输出结果:
四、强制类型转换
- byte 和 int 可以互相转换
- float 和 int 可以互相转换,小数位丢失
- bool 和 int 不能相互转换
- 不同长度的int 和 float 之间可以相互转换
- string 可以转换为 []byte 或 []rune 类型,byte 和 rune 可以转为 string
- 低精度向高精度转换没有问题,高精度向低精度转换会丢失位数
- 无符号向有符号转换,最高位是符号位
- int转字符时,要注意 string() 是将数值以编码(ASCII、UTF-8)形式进行转换,要保留数值转化需使用 strconv.Itoa(a)
范例:
func transformed() { a := 299870 fmt.Printf("a = %d\t[%b]\t\t(%T)\n", a, a, a) // int 转 int8 fmt.Printf("int->int8 = %d\t[%b]\t\t(%T)\n", int8(a), int8(a), int8(a)) // int 转 string s_a := string(rune(a)) s_conv := strconv.Itoa(a) fmt.Printf("int->string = '%s'\t\t(%T)\n", s_a, s_a) fmt.Printf("int->strconv.Itoa = '%s'\t\t(%T)\n", s_conv, s_conv) // int 转 float32 fmt.Printf("int->float32 = %f\t[%b]\t\t(%T)\n", float32(a), float32(a), float32(a)) fmt.Printf("\n") f := 3.5415926 fmt.Printf("f = %f\t[%b]\t\t(%T)\n", f, f, f) // float32 转 int16 fmt.Printf("float32->int16 = %d\t[%b]\t\t(%T)\n", int16(f), int32(f), int32(f)) }
输出结果: