Go语言基础数据类型之基本数据类型
Go语言基础数据类型之基本数据类型
Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。Go 语言的基本类型和其他语言大同小异。
基本数据类型
整型
整型分为两大类
按长度分为:
- Int8 、int16、int32、int64
对应无符号类型:
- uint8 、uint16、uint32 、uint64
uit8
是我们熟知的 byte
型
int16
对应C语言中的short
型
int64
对应C语言中的long
型
类型 | 描述 |
---|---|
uint8 | 无符号 8位整型 (0 到 255) |
uint16 | 无符号 16位整型 (0 到 65535) |
uint32 | 无符号 32位整型 (0 到 4294967295) |
uint64 | 无符号 64位整型 (0 到 18446744073709551615) |
int8 | 有符号 8位整型 (-128 到 127) |
int16 | 有符号 16位整型 (-32768 到 32767) |
int32 | 有符号 32位整型 (-2147483648 到 2147483647) |
int64 | 有符号 64位整型 (-9223372036854775808 到 9223372036854775807) |
特殊类型
类型 | 描述 |
---|---|
uint | 32位操作系统上就是uint32 ,64位操作系统上就是uint64 |
int | 32位操作系统上就是int32 ,64位操作系统上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
注意: 在使用int
和 uint
类型时,不能假定它是32位或64位的整型,而是考虑int
和uint
可能在不同平台上的差异。
注意:
注意事项 获取对象的长度的内建len()
函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以用int
来表示。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int
和 uint
。
数字字面量语法
Go1.13
版本之后引入了数字字面量语法,这样便于开发者,以二进制、八进制或十六进制浮点点数的格式定义数字,例如:
v := 0b00101101
代表二进制101101
,相当于十进制的45
v := 0o377
,代表八进制的377,相当于十进制的255
v := 0x1p-2
,代表十六进制的 1 除以 2²,也就是 0.25。- 还允许我们用
_
来分隔数字,比如说:v := 123_456
表示 v 的值等于 123456
以上代码用过了 fmt 包的格式化功能,你可以参考这里去看上面的代码
%b 表示为二进制
%c 该值对应的unicode码值
%d 表示为十进制
%o 表示为八进制
%q 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x 表示为十六进制,使用a-f
%X 表示为十六进制,使用A-F
%U 表示为Unicode格式:U+1234,等价于"U+%04X"
借助fmt函数将一个整数转换不同的进制形式展示.
package main
import "fmt"
func main() {
var a int = 10 // 十进制
fmt.Printf("%d \n",a) // %d 表示十进制
fmt.Printf("%b \n",a) // %b 表示二进制
var b int = 077 //以0开头的 代表八进制
fmt.Printf("%o \n",b) // %o 占位符 显示八进制
var c int = 0xff // 十六进制 以0x开头
fmt.Printf("%x \n",c) // %x 表示十六进制
fmt.Printf("%X \n",c)
}
结果:
10
1010
77
ff
FF
Process finished with exit code 0
浮点型
Go语言支持 两种浮点数类型:
两种浮点数类型数据格式遵循IEEE 754
标准 百度百科
float32
的浮点数的最大范围约为3.4e38
,可以使常量定义:math.MaxFloat32
float64
的浮点数的最大范围约为1.8e308
可以使常量定义:math.MaxFloat64
打印浮点数时可以,使用 fmt
包含动词 %f
例子:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("%f \n", math.MaxFloat32) // MaxFloat32 最大范围
fmt.Printf("%f \n", math.MaxFloat64) //MaxFloat64 最大范围
var a float64 = 3.1415926 // 推荐用 float64 更为精确
var b float32 = 3.1415926
fmt.Printf("float64: %f \n", a)
fmt.Printf("float32: %f \n", b)
fmt.Printf("%f \n", math.Pi)
fmt.Printf("%.2f \n", math.Pi) // %.2f 表示精确前两位
结果:
MaxFloat32: 340282346638528859811704183484516925440.000000
MaxFloat64: 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000
float64: 3.141593
float32: 3.141593
3.141593
3.14
Process finished with exit code 0
Go语言 默认浮点数类型 float64
有可能 你是32位系统就默认成 float32
package main
import (
"fmt"
"reflect"
)
func main() {
var a = 3.1415926 // 默认 float64
fmt.Println(reflect.TypeOf(a)) // reflect.TypeOf 判断当前变量 数据类型行
}
结果:
float64
Process finished with exit code 0
复数
一代而过: 我是数学不太好, 几乎也用不上, 可能我还没到那个水平.
complex64和complex128
package main
import (
"fmt"
)
func main() {
var c1 complex64
c1 = 1 + 2i
var c2 complex128
c2 = 2 + 3i
fmt.Println(c1)
fmt.Println(c2)
}
结果:
(1+2i)
(2+3i)
Process finished with exit code 0
布尔值
Go 语言中 以bool
类型生命的变量或者常量, 布尔类型只有
true
真false
假
package main
import "fmt"
func main() {
var a bool
fmt.Println(a) // Go语言中 默认值 为 false
var b bool = true // bool类型 不能强制转换 只有 真(true) 或者 假(false)
var c bool = false
fmt.Println(b)
fmt.Println(c)
}
结果:
false
true
false
Process finished with exit code 0
注意:
- 布尔类型变量的默认值为
false
。 - Go 语言中不允许将整型强制转换为布尔型.
- 布尔型无法参与数值运算,也无法与其他类型进行转换。
字符串
Go语言中的字符串以原生数据类型出现, 使用字符串就像是使用其他原生数据类型(int、bool、float32、float64等)一样.
- Go语言中字符串内部实现使用
utf-8
的编码方式 - 字符串的值是以
""
双引号的方式出现的 - 可以在Go语言的源码中直接添加非ASCII码字符
代码:
package main
import "fmt"
func main() {
s1 := "hello"
s2 := "你好"
fmt.Println(s1)
fmt.Println(s2)
}
结果:
hello
你好
Process finished with exit code 0
字符串转义符
go语言的字符串常见转义符包含回车、换行、单引号、制表符 等等.
转义符 | 含义 |
---|---|
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
举个例子,我们要打印一个Windows平台下的一个文件路径:
package main
import (
"fmt"
)
func main() {
a := `str := "c:\Code\lesson1\go.exe\"` // `` 表示字符串原样输出
fmt.Println(a)
b := "str := \"c:\\Code\\lesson1\\go.exe\\\"" // 转义符转换成普通字符串
fmt.Println(b)
}
结果:
str := "c:\Code\lesson1\go.exe\"
str := "c:\Code\lesson1\go.exe\"
Process finished with exit code 0
多行字符串
Go语言中 要定义个多行字符串 我们就必须使用 反引号
:
package main
import "fmt"
func main() {
s1 := `
name : 春生
age : 18
第三行 ...
`
fmt.Println(s1)
}
结果:
name : 春生
age : 18
第三行 ...
Process finished with exit code 0
字符串常用操作
方法 | 介绍 |
---|---|
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
代码 :
package main
import (
"fmt"
"strings"
)
func main() {
s1 := "北京吴彦祖春生" // utf-8 中文占用三个字节
fmt.Println(len(s1)) // 长度 31
// 字符串拼接 推荐 用+号 语言内部做了优化
s2 := "牛逼"
fmt.Println(s1 + s2) // "北京吴彦祖春生" + "牛逼" = "北京吴彦祖春生牛逼"
fmt.Sprintf(s1, s2) // fmt.Sprintf 方式拼接
// 字符串 分割 strings.Split
s3 := "www.baidu.com"
fmt.Println(strings.Split(s3,".")) // 结果返回值是以切片的方式返回 [www baidu com]
// 字符串判断是否包含 strings.Contains
fmt.Println(strings.Contains(s1,"春生")) // 返回布尔值 true
// 判断字符串前缀
fmt.Println(strings.HasPrefix(s1,"北京")) // 返回值 true 如果不是 返回 false
// 判断字符串后缀
fmt.Println(strings.HasSuffix(s1,"生")) // 返回值 true
// 判断子串出选的位置
fmt.Println(strings.Index(s1,"吴")) // 返回字符串 子串首次出现的位置
fmt.Println(strings.LastIndex(s1,"吴")) // 返回字符串s中字符串sep最后一次出现的位置
// join 操作 将切片数据类型转换成字符串
fmt.Println(strings.Join([]string{"lcc","lyh","ry"},","))
}
结果:
21
北京吴彦祖春生牛逼
[www baidu com]
true
true
true
6
6
lcc,lyh,ry
Process finished with exit code 0
byte和rune类型
组成每个字符串的元素叫做字符,可以通过便利的方获取每个字符 用单引号
包起来的就是字符:
代码:
var a = '中' // 字符 byte 类型
var b = 'w' // 字符 byte 类型
Go语言的字符有以下两种:
uint8
类型,或者叫byte型,代表ASCII的一个字符.- rune类型,代表一个UTF-8字符.
当需要处理中文、或者日文或其他复合字符时,需要用rune
类型.rune
实际是一个int32
.
Go使用特殊的rune类型来处理 Unicode,让基于Unicode的文本处理更为方便,也可以使用byte型默认字符串处理,性能和扩展都需要照顾.
package main
import (
"fmt"
"reflect"
"strings"
)
func ByteFunc() {
var a = '中' // 如果不声明 var byte a = '中' Go语言默认 是rune utf-8
fmt.Println(reflect.TypeOf(a))
var s1 = "hello北京"
for i :=0;i < len(s1);i++{ // byte类型
fmt.Println(s1[i])
}
for _,v := range s1{ // rune 类型
fmt.Println(v)
}
}
func main() {
ByteFunc()
}
结果:
int32
h
e
l
l
o
å
ä
º
¬
104
101
108
108
111
21271 // 北
20140 // 京
Process finished with exit code 0
乱码的出现是因为 UTF-8编码下的中文汉字是由 3~4个字节组成的,所以我们不能简单的安装字节去便利一个包含中文的字符串,否则就会出现上面第一个 for 循环出现的乱码.
字符串底层是一个byte数组,所以可以和 []byte
类型互相转换.字符串是能修改的,字符串是由byte
字节组成,所以字符串的长度是byte
字节的长度.
rune
类型用来表示utf8字符,一个rune
由一个或多个byte
组成.
修改字符串
- 要修改字符串,需要先将其转换成
[]rune
或者[]byte
,完成后在转换成string
. - 无论哪种转换,都会重新分配内存空间,并复制字节数组
package main
import (
"fmt"
"reflect"
"strings"
)
func StringSet(){
s1 := "big"
// 强制类型转换 修改字符串
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1))
s2 := "蒋秋生"
runeS2 := []rune(s2)
runeS2[1] = '春'
fmt.Println(string(runeS2))
}
func main() {
StringSet()
}
结果:
pig
蒋春生
Process finished with exit code 0
类型转换
Go语言中只有强制类型转换,没有隐式类型转换.该语法只能在两个类型之间支持互相切换
go 不支持隐式转换类型,比如 :
package main
import "fmt"
func main() {
var a int64 = 3
var b int32
b = a
fmt.Printf("b 为 : %d", b)
}
结果:
cannot use a (type int64) as type int32 in assignment
cannot use b (type int32) as type string in argument to fmt.Printf
强制类型转换基本语法如下:
package main
import "fmt"
func main() {
var a int64 = 3
var b int32
b = int32(a) // 转换之后在赋值。强制转换
fmt.Printf("b 为 : %d", b)
}
比如计算直角三角形的斜边长时使用math包的Sqrt()函数,该函数接收的是float64类型的参数,而变量a和b都是int类型的,这个时候就需要将a和b强制类型转换为float64类型。
func sqrtDemo() {
var a, b = 3, 4
var c int
// math.Sqrt()接收的参数是float64类型,需要强制转换
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)
}
练习题
1.编写代码分别定义一个整型、浮点型、布尔型、字符串型变量,使用fmt.Printf()
搭配%T
分别打印出上述变量的值和类型。
package main
import (
"fmt"
"reflect"
"strings"
)
func Exercises(){
// 编写代码分别定义一个整型、浮点型、布尔型、字符串型变量,使用`fmt.Printf()`搭配`%T`分别打印出上述变量的值和类型。
var a int = 10
var pi float64 = 3.1415926
var isOk bool = true
var str string = "春生"
fmt.Printf("数值:%d 类型:%T \n",a,a)
fmt.Printf("数值:%f 类型:%T \n",pi,pi)
fmt.Printf("数值:%t 类型:%T \n",isOk,isOk)
fmt.Printf("数值:%s 类型:%T \n",str,str)
}
func main() {
Exercises()
}
结果:
数值:10 类型:int
数值:3.141593 类型:float64
数值:true 类型:bool
数值:春生 类型:string
2.编写代码统计出字符串"hello北京吴彦祖春生"
中汉字的数量。
package main
import (
"fmt"
"reflect"
"strings"
)
func Exercises(){
// 编写代码统计出字符串`"hello北京吴彦祖春生"`中汉字的数量。
s1 := "hello北京吴彦祖春生"
num := 0
for _,v:=range s1 {
if len(string(v)) >= 3{
num++
}
}
fmt.Println("共有",num,"汉字")
}
func main() {
Exercises()
}
结果:
共有 7 汉字
Process finished with exit code 0
3.字符串反转
package main
import (
"fmt"
"reflect"
"strings"
)
func StrReverse(){
// 字符串反转
s1 := "hello"
byteArray := []byte(s1)
s2 := ""
for i :=len(byteArray)-1;i>=0;i--{
s2 += string(byteArray[i])
}
fmt.Println(s2)
}
func main() {
StrReverse()
}
结果:
olleh
Process finished with exit code 0