在go语言中,数据类型用于声明函数和变量。
数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才去申请大内存,需要小数据的时候就去申请小的内存,就可以充分利用空间。
go语言按类别有以下几种数据:
类型 | 描述 |
---|---|
布尔类型 | 布尔类型的值只可以是常量true或false。一个简单的例子:var flag=true |
数字类型 | 数字类型包括整型int,浮点型float32和浮点型float64;同时支持复数。(注意:不能用0或者非0表示条件判断) |
字符串类型 | 字符串就是一串固定长度的字符连接起来的字符序列。go语言的字符串是由单个字节连接起来的,go语言的字符串的字节使用utf8编码标识unicode文本。 |
派生类型 | 派生类型包括:指针类型,数组类型,切片类型,结构体类型,channel类型,接口类型,map类型等等 |
go语言也有基于架构的类型,例如:int,uint和uintptr。
类型 | 描述 |
---|---|
uint8 | 无符号8位整型(0到255) |
uint16 | 无符号16位整数(0到65535) |
uint32 | 无符号32位整数(0到4294967295) |
uint64 | 无符号64位整数(0到18446744073709551616) |
int8 | 有符号8位整数(-128到127) |
int16 | 有符号16位整数(-32768到32767) |
int32 | 有符号32位整数(-2147483648到2147483647) |
int64 | 有符号64位整数(-9223372036854775808到9223372036854775807) |
package main
import (
"fmt"
"math"
"unsafe"
)
func main() {
var a uint8
var b uint16
var c uint32
var d uint64
fmt.Printf("a: %v %T %dB %v~%v\n", a, a, unsafe.Sizeof(a), 0, math.MaxUint8)
fmt.Printf("b: %v %T %dB %v~%v\n", b, b, unsafe.Sizeof(b), 0, math.MaxUint16)
fmt.Printf("c: %v %T %dB %v~%v\n", c, c, unsafe.Sizeof(c), 0, math.MaxUint32)
fmt.Printf("d: %v %T %dB %v~%v\n", d, d, unsafe.Sizeof(d), 0, math.MaxInt64)
var e int8
var f int16
var g int32
var h int64
fmt.Printf("e: %v %T %dB %v~%v\n", e, e, unsafe.Sizeof(e), math.MinInt8, math.MaxInt8)
fmt.Printf("f: %v %T %dB %v~%v\n", f, f, unsafe.Sizeof(f), math.MinInt16, math.MaxInt16)
fmt.Printf("g: %v %T %dB %v~%v\n", g, g, unsafe.Sizeof(g), math.MinInt32, math.MaxInt32)
fmt.Printf("h: %v %T %dB %v~%v\n", h, h, unsafe.Sizeof(h), math.MinInt64, math.MaxInt64)
var i float32
var j float64
fmt.Printf("i: %v %T %dB %v~%v\n", i, i, unsafe.Sizeof(i), -math.MaxFloat32, math.MaxFloat32)
fmt.Printf("j: %v %T %dB %v~%v\n", j, j, unsafe.Sizeof(j), -math.MaxFloat64, math.MaxFloat64)
var k complex64
var l complex128
fmt.Printf("k: %v %T %dB \n", k, k, unsafe.Sizeof(k))
fmt.Printf("l: %v %T %dB \n", l, l, unsafe.Sizeof(l))
}
/*
a: 0 uint8 1B 0~255
b: 0 uint16 2B 0~65535
c: 0 uint32 4B 0~4294967295
d: 0 uint64 8B 0~9223372036854775807
e: 0 int8 1B -128~127
f: 0 int16 2B -32768~32767
g: 0 int32 4B -2147483648~2147483647
h: 0 int64 8B -9223372036854775808~9223372036854775807
i: 0 float32 4B -3.4028234663852886e+38~3.4028234663852886e+38
j: 0 float64 8B -1.7976931348623157e+308~1.7976931348623157e+308
k: (0+0i) complex64 8B
l: (0+0i) complex128 16B
*/
package main
import "fmt"
func main() {
//十进制的数
a := 10
fmt.Printf("a的十进制表示a: %d\n", a)
fmt.Printf("a的二进制表示a: %b\n", a)
fmt.Printf("a的八进制表示a: %o\n", a)
fmt.Printf("a的十六进制表示a: %x\n", a)
//定义一个八进制的数 以0开头
b := 077
fmt.Printf("b的十进制表示a: %d\n", b)
fmt.Printf("b的二进制表示a: %b\n", b)
fmt.Printf("b的八进制表示a: %o\n", b)
fmt.Printf("b的十六进制表示a: %x\n", b)
//定义一个十六进制的数 以0x开头
c := 0x111
fmt.Printf("c的十进制表示a: %d\n", c)
fmt.Printf("c的二进制表示a: %b\n", c)
fmt.Printf("c的八进制表示a: %o\n", c)
fmt.Printf("c的十六进制表示a: %x\n", c)
}
类型 | 描述 |
---|---|
float32 | IEEE-754 32位浮点型数 |
float64 | IEEE-754 64位浮点型数 |
complex64 | 32位实数和虚数 |
complex128 | 64位实数和虚数 |
类型 | 描述 |
---|---|
byte | 类似uint8 |
rune | 类似int32 |
在go语言中,字符串使用双引号""或者反引号来创建。双引号用来创建可解析的字符串,支持转义,但不能用来引用多行;反引号用来创建原生的字符串,可由多行组成,但不支持转义,并且可以包含除了反引号外其他所有字符。双引号创建可解析的字符串应用最广泛,反引号用来创建原生的字符串多用于书写多行消息,HTML以及正则表达式。
package main
import (
"bytes"
"fmt"
"strings"
)
func main() {
//单行字符串 支持转义
a := "hello world"
//多行字符串 不支持转义
b := `
hello
`
fmt.Printf("a: %v\n", a)
fmt.Printf("b: %v\n", b)
//字符串的拼接
s1 := "hello"
s2 := "world"
//1.加号拼接
res1 := s1 + " " + s2
fmt.Printf("s: %v\n", res1)
//2.字符串格式化 Sprintf
res2 := fmt.Sprintf("%s %s", s1, s2)
fmt.Printf("res2: %v\n", res2)
//3.strings.join()
/*
join会根据字符串数组得到内容,计算出一个拼接之后的字符串的长度,然后申请对应大小的内存,一个一个字符填入,
在已有一个数组的情况下,这种效率会很高,但是本来没有,去构造这个数组的代价也很高
*/
res3 := strings.Join([]string{s1, s2}, " ") //第一个参数是字符串数组,第二个参数是连接符
fmt.Printf("res3: %v\n", res3)
//4.buffer.WriteString()
/*
这个比较理想,可以当成可变字符串使用,对内存的增长也有优化,如果能预估字符串的长度,还可以使用buffer.Grow()接口来设置capacity
同时这是直接写到缓冲区,因此效率比较高
*/
var buffer bytes.Buffer
buffer.WriteString(s1)
buffer.WriteString(s2)
fmt.Printf("buffer.String(): %v\n", buffer.String())
}
go语言的字符串常见的转义字符包含回车,换行,单双引号,制表符等
转义符 | 含义 |
---|---|
\r | 回车符号 |
\n | 换行符 |
\t | 制表符(tab键,或者四个空格) |
\’ | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
//切片操作
s := "I am a student."
m, n := 2, 4
fmt.Printf("s[m:n]: %v\n", s[m:n]) //获取字符串s索引位置从m到n-1的值
fmt.Printf("s[:n]: %v\n", s[:n]) //获取字符串s索引位置从0到n-1的值
fmt.Printf("s[m:]: %v\n", s[m:]) //获取字符串s索引位置从m到len(s)-1的值
fmt.Printf("s[:]: %v\n", s[:]) //获取字符串s
fmt.Printf("s[m]: %v\n", s[m]) //获取字符串s索引位置m的字符的ascii值
方法 | 描述 |
---|---|
len(s) | 获取字符串s的长度 |
+或者fmt.Sprintf | 拼接字符串 |
strings.Split(s,seq) | 用分隔符seq分割字符s |
strings.Contains(s,subs) | 查询字符串s中是否包含子串subs |
strings.HasPrefix(s,prefix)/strings.HasSuffix(s,suffix) | 判断前/后缀是否是指定的字符串 |
strings.Index(s,subs)/strings.LastIndex(s,subs) | 查询子串subs在s中第一次(最后一次)出现的索引位置,若没有则返回-1 |
strings.join(s_arr,seq) | 将字符串数组用seq拼接成一个字符串 |
//分割字符串
fmt.Printf("strings.Split(s, \" \"): %v\n", strings.Split(s, " "))
//查询某个字符串是否包含指定的字符串
fmt.Printf("strings.Contains(s, \"student\"): %v\n", strings.Contains(s, "student"))
//判断前缀是否是指定的字符串
fmt.Printf("strings.HasPrefix(s, \"hello\"): %v\n", strings.HasPrefix(s, "hello"))
//判断后缀是否是指定的字符串
fmt.Printf("strings.HasSuffix(s, \"student.\"): %v\n", strings.HasSuffix(s, "student."))
//查找指定字符串第一次出现的索引位置
fmt.Printf("strings.Index(s, \"a\"): %v\n", strings.Index(s, "aaa"))
//查找指定字符串最后一次出现的索引位置
fmt.Printf("strings.LastIndex(s, \"a\"): %v\n", strings.LastIndex(s, "a"))
//拼接字符串数组
fmt.Printf("strings.Join([]string{\"i\", \"am\", \"a\", \"student.\"}, \" \"): %v\n", strings.Join([]string{"i", "am", "a", "student."}, " "))
运行结果
strings.Split(s, " "): [I am a student.]
strings.Contains(s, "student"): true
strings.HasPrefix(s, "hello"): false
strings.HasSuffix(s, "student."): true
strings.Index(s, "a"): -1
strings.LastIndex(s, "a"): 5
strings.Join([]string{"i", "am", "a", "student."}, " "): i am a student.
占位符 | 说明 | 举例 |
---|---|---|
%v | 相应值的默认格式。 | fmt.Printf(“a: %v\n”, 100) ----> a:100 |
%#v | 会打印出数据的完整格式。 | tom := studnet{“Tom”}fmt.Printf(“tom: %#v\n”, tom) ---->tom: main.studnet{Name:“Tom”} |
%T | 相应值的类型。 | fmt.Printf(“a: %T\n”, 100) ----> a:int |
%% | 输出%。 | fmt.Printf(“%%”) ---->% |
//相应数据的默认格式
a := 10
fmt.Printf("a: %#v\n", a)
tom := studnet{"Tom"}
//数据的完整格式
fmt.Printf("tom: %#v\n", tom)
//%
fmt.Printf("%%\n")
运行结果
a: 10
tom: main.studnet{Name:"Tom"}
%
占位符 | 说明 | 举例 |
---|---|---|
%t | 输出true或false。 | fmt.Printf(“flag: %t\n”, true) ---->true |
//布尔占位符
flag := true
fmt.Printf("flag: %t\n", flag)
运行结果
flag: true
占位符 | 说明 | 举例 |
---|---|---|
%b | 输出二进制表示 | fmt.Printf(“%b\n”, 10) ---->1010 |
%c | 相应的Unicode码值所表示的码符 | fmt.Printf(“%c\n”,97) ---->a |
%d | 输出十进制表示 | fmt.Printf(“%d\n”, 10) ---->10 |
%o | 输出八进制表示 | fmt.Printf(“%o\n”, 10) ---->12 |
%x | 十六进制表示(小写字母) | fmt.Printf(“%x\n”, 10) ---->a |
%X | 十六进制表示(大写字母) | fmt.Printf(“%X\n”, 10) ---->A |
%q | 单引号围绕的字符字面值,由go语法安全的转义 | fmt.Printf(“%q\n”, 10) ---->‘\n’ |
%U | Unicode格式:U+1234等同于“U+%04X” | fmt.Printf(“%U\n”, 10) ---->U+000A |
//二进制输出
fmt.Printf("%b\n", 10)
//相应的Unicode码值对应的码符
fmt.Printf("%c\n", 97)
//八进制
fmt.Printf("%o\n", 10)
//十六进制 小写字母
fmt.Printf("%x\n", 10)
//十六进制 大写字母
fmt.Printf("%X\n", 10)
fmt.Printf("%q\n", 10)
fmt.Printf("%U\n", 10)
运行结果
1010
a
12
a
A
'\n'
U+000A
占位符 | 说明 | 举例 |
---|---|---|
%b | 无小数部分的,指数为二的幂的科学计数法,与strconv.FormatFloat的’b’转换格式一样 | fmt.Printf(“%b\n”, 10.1) ---->5685794529555251p-49 |
%e | 科学计数法(小写字母) | fmt.Printf(“%e\n”, 10.1) ---->1.010000e+01 |
%E | 科学计数法(大写字母) | fmt.Printf(“%E\n”, 10.1) ---->1.010000E+01 |
%f | 有小数点而无指数 | fmt.Printf(“%5.2f\n”, 10.1) ---->10.10(总长度为5,小数点两位) |
%g | 根据情况选择%e或%f以产生更紧凑的输出(无末尾的0) | fmt.Printf(“%g\n”, 10.10000) ---->10.1 |
%G | 根据情况选择%E或%f以产生更紧凑的输出(无末尾的0) | fmt.Printf(“%G\n”, 10.000+2.0600i) ---->(10+2.06i) |
//浮点数和复数
fmt.Printf("%b\n", 10.1)
fmt.Printf("%e\n", 10.1)
fmt.Printf("%E\n", 10.1)
fmt.Printf("2%5.2f2\n", 10.1)
fmt.Printf("%g\n", 10.10000)
fmt.Printf("%G\n", 10.000+2.0600i)
运行结果
5685794529555251p-49
1.010000e+01
1.010000E+01
210.102
10.1
(10+2.06i)
占位符 | 说明 | 举例 |
---|---|---|
%s | 输出字符串表示(string类型或[]byte类型) | fmt.Printf(“[]byte{“hello”, “world”}: %s\n”, []byte(“hello”)) ---->[]byte{“hello”, “world”}: hello |
%q | 双引号围绕的字符串,由go语言安全地转义 | fmt.Printf(““hello”: %q\n”, “hello”) ---->“hello” |
%x | 十六进制,小写字母,每字节两个字符 | fmt.Printf(““hello”: %x\n”, “hello”) ---->“hello”: 68656c6c6f |
%X | 十六进制,大写字母,每字节两个字符 | fmt.Printf(““hello”: %X\n”, “hello”) ---->“hello”: 68656C6C6F |
//字符串
fmt.Printf("[]byte{\"hello\", \"world\"}: %s\n", []byte("hello"))
fmt.Printf("\"hello\": %q\n", "hello")
fmt.Printf("\"hello\": %x\n", "hello")
fmt.Printf("\"hello\": %X\n", "hello")
运行结果
[]byte{"hello", "world"}: hello
"hello": "hello"
"hello": 68656c6c6f
"hello": 68656C6C6F
占位符 | 说明 | 举例 |
---|---|---|
%p | 十六进制表示,输出指针所指向的地址 | h := 100 p_h := &h fmt.Printf(“%p\n”, &h) fmt.Printf(“%p\n”, p_h) ---->两个输出是一样的:0xc0000ba018,都是输出的h的地址 |
h := 100
p_h := &h
fmt.Printf("h: %p\n", &h)
fmt.Printf("p_h: %p\n", p_h)
运行结果
h: 0xc0000140f8
p_h: 0xc0000140f8
go语言内置的运算符有:
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 取模(求余) |
注意:++(自增)和–(自减)在go语言中是单独的语句,并不是运算符。
a := 100
b := 200
//算术运算符
res := a + b
fmt.Printf("res: %v\n", res)
res = a - b
fmt.Printf("res: %v\n", res)
res = a * b
fmt.Printf("res: %v\n", res)
res = a / b
fmt.Printf("res: %v\n", res)
res = a % b
fmt.Printf("res: %v\n", res)
a++
运行结果
res: 300
res: -100
res: 20000
res: 0
res: 100
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,返回true或false |
!= | 检查两个值是否不相等,返回true或false |
> | 检查左边的值是否大于右边的值,返回true或false |
>= | 检查左边的值是否大于等于右边的值,返回true或false |
< | 检查左边的值是否小于右边的值,返回true或false |
<= | 检查左边的值是否小于等于右边的值,返回true或false |
// 关系运算符
var res2 bool
res2 = a == b
fmt.Printf("res2: %v\n", res2)
res2 = a > b
fmt.Printf("res2: %v\n", res2)
res2 = a >= b
fmt.Printf("res2: %v\n", res2)
res2 = a < b
fmt.Printf("res2: %v\n", res2)
res2 = a <= b
fmt.Printf("res2: %v\n", res2)
res2 = a != b
fmt.Printf("res2: %v\n", res2)
运行结果
res2: false
res2: false
res2: false
res2: true
res2: true
res2: true
运算符 | 描述 |
---|---|
&& | 逻辑and运算符。只有两边的操作数都为true才返回true,否则返回false。 |
|| | 逻辑or运算符。只要有一个操作数为true就返回true,否则返回false。 |
! | 逻辑not运算符。取相反的结果。 |
//逻辑运算
var res3 bool
res3 = true && true
fmt.Printf("res3: %v\n", res3)
res3 = true || false
fmt.Printf("res3: %v\n", res3)
res3 = !res3
fmt.Printf("res3: %v\n", res3)
res3: true
res3: true
res3: false
位运算是对整数在内存中的二进制位进行操作。
运算符 | 描述 |
---|---|
& | 参与运算的两个数各对应的二进位相与。(两位均为1才为1) |
| | 参与运算的两个数各对应的二进位相或。(两位只要有一个为1就为1) |
^ | 参与运算的两个数各对应的二进位异或。(当相对应的二进位相异时,结果才为1,否则为0) |
<< | 左移n位就是乘以2的n次方。a< |
<< | 右移n位就是除以2的n次方。a>>b是把a的各二进位全部右移b位。 |
//位运算
aa := 10
bb := 11
fmt.Printf("aa: %b\n", aa)
fmt.Printf("bb: %b\n", bb)
res4 := aa & bb
fmt.Printf("res4:%b %v\n", res4, res4)
res4 = aa | bb
fmt.Printf("res4:%b %v\n", res4, res4)
res4 = aa ^ bb
fmt.Printf("res4:%b %v\n", res4, res4)
res4 = aa << 2
fmt.Printf("res4:%b %v\n", res4, res4)
res4 = aa >> 1
fmt.Printf("res4:%b %v\n", res4, res4)
运行结果
aa: 1010
bb: 1011
res4:1010 10
res4:1011 11
res4:1 1
res4:101000 40
res4:101 5
运算符 | 描述 |
---|---|
= | 简单的赋值运算符,将等号右边的结果赋值给左边的变量。 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 取模后再赋值 |
<<= | 左移后再赋值 |
>>= | 右移后再赋值 |
&= | 按位与后赋值 |
|= | 按位或后赋值 |
^= | 异或后赋值 |
同步更新于个人博客系统:golang学习笔记系列之基本数据类型