目录
- 一、Go数据类型
- 二、字符串
- 三、强制类型转换
一、Go数据类型
- 基础数据类型
类型 | 长度(字节) | 默认值 | 说明 |
---|---|---|---|
bool | 1 | false | |
byte | 1 | uint8,取值范围[0,255] | |
rune | 4 | Unicode Code Point, int32 | |
int, uint | 4或8 | 32 或 64 位,取决于操作系统 | |
int8, uint8 | 1 | -128 ~ 127, 0 ~ 255 | |
int16, uint16 | 2 | -32768 ~ 32767, 0 ~ 65535 | |
int32, uint32 | 4 | -21亿~ 21亿, 0 ~ 42亿,rune是int32 的别名 | |
int64, uint64 | 8 | ||
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | |
complex64 | 8 | ||
complex128 | 16 | ||
uintptr | 4或8 | 以存储指针的 uint32 或 uint64 整数 |
func main() {
var m complex64
m = complex(2, 6)
fmt.Printf("%T %T\n", real(m), imag(m)) // float32 float32 实部32,虚部32,加起来就是64
fmt.Printf("real=%f img=%f\n", real(m), imag(m)) //real=2.000000 img=6.000000
var n complex128
n = complex(2, 6)
fmt.Printf("%T %T\n", real(n), imag(n)) //float64 float64 实部64,虚部64,加起来就是128
fmt.Printf("real=%f img=%f\n", real(n), imag(n)) //real=2.000000 img=6.000000
}
- 三种指针类型都是同一个地址
func main() {
var a int
// unsafe.Pointer 是特别定义的一种指针类型,它可以包含任意类型变量的地址(类似 C 语言中的 void 类型指针)
var pointer unsafe.Pointer = unsafe.Pointer(&a)
var p uintptr = uintptr(pointer)
var ptr *int = &a
fmt.Printf("pointer=%p , p=%d %x, ptr=%p\n", pointer, p, p, ptr)
//pointer=0xc0000a6058 , p=824634400856 c0000a6058, ptr=0xc0000a6058
}
- 复合数据类型:
- 数值型变量的默认值是0,字符串的默认值是空字符串,布尔型变量的默认值是false
- 引用类型、函数、指针、接口的默认值是nil
- 数组的默认值取每个元素对应类型的默认值
- 结构体的默认值取每个成员变量对应类型的默认值
类型 | 默认值 | 说明 |
---|---|---|
array | 取每个元素对应类型的默认值 | 值类型 |
struct | 取每个成员变量对应类型的默认值 | 值类型 |
string | “” | UTF-8 字符串 |
slice | nil | 引用类型 |
map | nil | 引用类型 |
channel | nil | 引用类型 |
interface | nil | 接口 |
function | nil | 函数 |
func defaultValue() {
var a int
var b byte
var f float32
var t bool
var s string
var r rune
var arr [3]int
var slc []int
fmt.Printf("default value of int %d\n", a) //default value of int 0
fmt.Printf("default value of byte %d\n", b) //default value of byte 0
fmt.Printf("default value of float32 %.2f\n", f) //default value of float32 0.00
fmt.Printf("default value of bool %t\n", t) //default value of bool false
fmt.Printf("default value of string [%s]\n", s) //default value of string []
fmt.Printf("default value of rune %d, [%c]\n", r, r) //default value of rune 0, []
fmt.Printf("default int array is %v\n", arr) //取每个元素对应类型的默认值 default int array is [0 0 0]
fmt.Printf("default slice is nil %t\n", slc == nil) //default slice is nil true
}
- 自定义类型
- 类型别名
-
type byte = uint8
-
type rune = int32
-
- 自定义类型
-
type user struct {name string;age int}
-
type signal uint8
-
type ms map[string]string
-
type add func(a, b int) int
-
- 类型别名
type ms map[string]int
func (s ms) Say() {
fmt.Printf("%d\n", s["hello"])
}
二、字符串
- 字符串定义
package main
import "fmt"
func main() {
s1 := " My name is 张朝阳☻" //字符串里可以包含任意Unicode字符
s2 := "He say:\"I'm fine.\" \n\\Thank\tyou.\\" //字符串里可以包含任意Unicode字符
//字符串也可以用反引号来定义,反引号里的转义字符无效。反引号里的内容原封不动地输出,包括空白符和换行符
s3 := `here is first line.
there is third line.
`
fmt.Printf("%s\n", s1)
fmt.Printf("%s\n", s2)
fmt.Printf("%s\n", s3)
}

- 字符串常用操作
方法 | 介绍 |
---|---|
len(str) | 求长度 |
strings.Split | 分割 |
strings.Contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
func main() {
s := "张"
arr := []byte(s)
for _, ele := range arr { //一个汉字占用3个byte表示
fmt.Printf("%d ", ele) // 229 188 160
}
fmt.Println()
fmt.Printf("%d %d\n", len(s), len(arr)) //3 3
brr := []rune(s)
for _, ele := range brr { //一个rune就可以表示一个汉字
fmt.Printf("%d ", ele) // 24352
}
fmt.Println()
fmt.Printf("%d %d", len(s), len(brr)) //3 1
}
//
func main() {
s := "张2"
arr := []byte(s)
brr := []rune(s)
fmt.Printf("%d %c\n", s[1], s[1]) //188 ¼
fmt.Printf("%d %c\n", arr[1], arr[1]) //188 ¼
fmt.Printf("%d %c\n", brr[1], brr[1]) //50 2(字符2,在Unicode编码中为50)
}
//
func main() {
s := "hello, how are u"
arr := strings.Split(s, ",")
for _, ele := range arr {
fmt.Println(ele)
//hello
// how are u
}
fmt.Printf("%t\n", strings.Contains(s, "how")) //true
fmt.Printf("%t\n", strings.HasPrefix(s, "he")) //true
fmt.Printf("%t\n", strings.HasPrefix(s, "hE")) //false
fmt.Printf("%t\n", strings.HasSuffix(s, " u")) //true
fmt.Printf("%t\n", strings.HasSuffix(s, "a")) //false
pos := strings.Index(s, "lo")
fmt.Printf("%d\n", pos) //3
fmt.Printf("%d\n", strings.Index(s, "e")) //1(首次出现e的位置)
fmt.Printf("%d\n", strings.LastIndex(s, "e")) //13(最后出现e的位置)
fmt.Printf("%d\n", strings.IndexAny(s, "oe")) //1(查找任意一个字符的位置)
}
- 字符串拼接
- 加号连接
- func fmt.Sprintf(format string, a …interface{}) string
- func strings.Join(elems []string, sep string) string
- 当有大量的string需要拼接时,用strings.Builder效率最高
- byte和rune
- string中每个元素叫“字符”,字符有两种
- byte:1个字节, 代表ASCII码的一个字符
- rune:4个字节,代表一个UTF-8字符,一个汉字可用一个rune表示
- string是常量,不能修改其中的字符
- string可以转换为[]byte或[]rune类型
- string的底层是byte数组,string的长度就是该byte数组的长度,UTF-8编码下一个汉字占3个byte,即一个汉字占3个长度
- string中每个元素叫“字符”,字符有两种
func main() {
s1 := "aaa"
s2 := "bbb"
s3 := "ccc"
S1 := s1 + " " + s2 + " " + s3
S2 := fmt.Sprintf("%s %s %s", s1, s2, s3)
S3 := strings.Join([]string{s1, s2, s3}, " ") //性能较高
sb := strings.Builder{} //性能最高
sb.WriteString(s1)
sb.WriteString(" ")
sb.WriteString(s2)
sb.WriteString(" ")
sb.WriteString(s3)
S4 := sb.String()
fmt.Println(S1) //aaa bbb ccc
fmt.Println(S2) //aaa bbb ccc
fmt.Println(S3) //aaa bbb ccc
fmt.Println(S4) //aaa bbb ccc
}
三、强制类型转换
- 强制类型转换:基本方法就是把目标类型放在变量前面,把变量括起来
- 低精度向高精度转换没问题,高精度向低精度转换会丢失位数
- 无符号向有符号转换,最高位是符号位
- 不同长度的int或float之间可以相互转换
- byte和int可以互相转换;float和int可以互相转换,小数位会丢失;bool和int不能相互转换
func main() {
var i int = 9
var by byte = byte(i) //int转为byte
i = int(by) //byte转为int
//高精度向低精度转换,数字很小时这种转换没问题
var ua uint64 = 1
i8 := int8(ua)
fmt.Printf("i8=%d\n", i8) //i8=1
//最高位的1变成了符号位
ua = uint64(math.MaxUint64)
i64 := int64(ua)
fmt.Printf("i64=%d\n", i64) //i64=-1
//位数丢失
ui32 := uint32(ua)
fmt.Printf("ui32=%d\n", ui32) //ui32=4294967295
//单个字符可以转为int
var i int = int('a')
fmt.Printf("i=%d\n", i) //97
//bool和int不能相互转换
//byte和int可以互相转换
var by byte = byte(i)
i = int(by)
fmt.Printf("i=%d\n", i) //97
//float和int可以互相转换,小数位会丢失
var ft float32 = float32(i)
i = int(ft)
fmt.Printf("i=%d\n", i) //97
}