Go基础语法:基本数据类型

3 基本数据类型

基本数据类型包括:整型、浮点型、布尔型、字符串。

除以上基本类型之外,还有 数组、切片、结构体、函数、map、通道 等。

3.1 整型

3.1.1 整型

整型分为:int8int16int32int64 ,以及对应的无符号整型:uint8uint16uint32uint64

其中 unit8 对应其他语言中的 byte 类型;int16 对应 C 语言中的 short 类型;int64 对应 C 语言中的 long 类型。

各数据类型及对应的取值关系如下:

特殊整型:

注意: 获取对象的长度时,内建的 len() 函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以直接使用 int 来表示 。

3.1.2 八进制和十六进制

go 复制代码
package main

import (
	"fmt"
)

func main() {
	// 声明十进制数.
	var a = 10
	// %d 为十进制数的占位符,表示输出十进制数------10
	fmt.Printf("%d \n", a)
	// %b 为二进制数的占位符,输出二进制数------1010
	fmt.Printf("%b \n", a)
	// %o 为八进制数的占位符,输出八进制数------12
	fmt.Printf("%o \n", a)
	// %x 为十六进制数的占位符,输出十六进制数------a
	fmt.Printf("%x \n", a)
	// %T 表示获取某个变量的类型_int
	fmt.Printf("%T \n", a)

	// 声明八进制数,以 0 开头
	b := 077
	// 63
	fmt.Printf("%d \n", b)
	//111111
	fmt.Printf("%b \n", b)
	// 77
	fmt.Printf("%o \n", b)
	// 3f
	fmt.Printf("%x \n", b)
	// int
	fmt.Printf("%T \n", b)

	// 声明 16 进制数,以 0x开头
	c := 0xff
	// 255
	fmt.Printf("%d \n", c)
	// 11111111
	fmt.Printf("%b \n", c)
	// 377
	fmt.Printf("%o \n", c)
	// ff
	fmt.Printf("%x \n", c)
	// int
	fmt.Printf("%T \n", c)

	// 显示声明为 int8 类型,否则,默认 int 类型
	d := int8(9)
	// 9
	fmt.Printf("%d \n", d)
	// 1001
	fmt.Printf("%b \n", d)
	// 11
	fmt.Printf("%o \n", d)
	// 9
	fmt.Printf("%x \n", d)
	// int8
	fmt.Printf("%T \n", d)

	// %v 表示获取某个变量的值------int8,9
	fmt.Printf("d 的类型为:%T,值为: %v", d, d)
}

3.2 浮点型

go 语言支持两种浮点型数,float32float64.

这两种浮点型数据格式遵循 IEEE 754 标准, float32 的浮点数的最大范围约为 3.4e38 ,可以使用常量定义:math.MaxFloat32。float64 的浮点数的最大范围约为 1.8e308, 可以使用常量定义 math.MaxFloat64

go 复制代码
package main

import (
	"fmt"
	"math"
)

func main() {
	// %f 为浮点数的占位符,
	fmt.Printf("%f \n", math.MaxFloat32)
	fmt.Printf("%f \n", math.MaxFloat64)

	var a = 1.2345
	// 默认 floa64
	fmt.Printf("%T \n", a)

	var b = float32(1.2345)
	// 显示声明为 float32
	fmt.Printf("%T \n", b)
}

3.3 复数

  • 复数实际上是有两个实数(浮点数)的组合,一个表示实部(real),一个表示虚部(imag)。
  • 虚部需要添加 i 作为后缀。
  • real(复数)可以获取实部 ,imag(复数) 可以获取虚部
  • complex64complex128 两种类型,complex64 的实部和虚部为 32 位,complex128 的实部和虚部为 64 位。
go 复制代码
package main

import "fmt"

func main() {
	// 1、声明一个复数
	var v1 complex64
	// 虚部数据需要后缀 i
	v1 = 3.2 + 12i
	fmt.Println("v1=", v1)

	// 2、自动推导类型的复数
	v2 := 3.3 + 2.0i
	fmt.Printf("v2的类型为:%T \n", v2)
	fmt.Println("v2的值为:", v2)

	// 3、获取复数的实部和虚部: real(复数),imag(复数)
	fmt.Println("v2的实部为:", real(v2), "v2的虚部为:", imag(v2))
}

运行结果:

cnpeng$ go run Day1.go 
v1= (3.2+12i)
v2的类型为:complex128 
v2的值为: (3.3+2i)
v2的实部为: 3.3 v2的虚部为: 2

3.4 布尔类型

3.4.1 布尔类型

go 语言中以 bool 声明布尔类型数据。布尔类型仅有 truefalse 两种值。

注意:

  • 布尔类型变量的默认值为 false
  • go 语言中不允许将整型强制转换为布尔类型
  • 布尔型数据无法参与数值运算,与无法与其他类型进行转换。

3.4.2 补充:格式化输出的总结

fmt 包的 Printf() 格式化输出可以使用下面的格式化符号:

格式 含义
%% % 字面量
%b 二进制整数值(基数为2),或者是(高级的)用科学计数法表示的指数为2的浮点数
%c 字符型。可以把输入的数字按照 ASCII 码转换为对应的字符。
%d 十进制数值(基数为10)
%e 以科学计数法 e 表示的浮点数或者复数值
%E 以科学计数法 E 表示的浮点数或者复数值
%f 以标准计数法表示的浮点数或者复数值
%g %e或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出
%G %E或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出
%o 以八进制表示的数字
%p 以十六进制表示的值的地址,前缀为 0x, 字母使用小小的 a-f 表示
%s 字符串
%t 以 true 或者 false 输出布尔值
%T 获取数据类型。
%U 用 Unicode 表示法表示的整型码点。默认值为四个数字字符
%v 使用默认格式输出的内置或自定义类型的值。或者时使用期望类型的 String() 方式输出的自定义值。
%#v 如果输出的字符串,该字符串会被双引号包裹起来
%x 以十六进制表示的整型值, a-f 使用小写
%X 以十六进制表示的整型值, A-F 使用大写
go 复制代码
package main

import (
	"fmt"
)

func main() {
	var str = "abc"
	// "abc" 
	fmt.Printf("%#v \n", str)
}

3.4 字符串

go 语言中的字符串以原生数据类型出现,使用字符串就想使用其他原生数据类型(int、bool、float32、float64 等)一样。

go 语言中字符串的内部实现使用了 UTF-8 编码。字符串的值使用双引号 " " 包裹 ( go 语言中,只有使用单引号 ' ' 包裹的是字符)。

3.4.1 字符串转义符

转义符 含义
\r 回车符(返回行首)
\n 换行符
\t 制表符
\' 单引号
\" 双引号
\\ 反斜杠

1字节=8Bit ,即1字节表示八个二进制位,也就是 八个 01------01010101

一个 UTF-8 编码的汉字通常占用三个字节,偏僻字可能会占四个字节。

go 复制代码
package main

import (
	"fmt"
)

func main() {
	// 打印 windows 下的一个文件目录,需要使用转义字符
	// 输出结果:"D:\Go\src\code.github.cnoeng\stu"
	fmt.Printf("\"D:\\Go\\src\\code.github.cnoeng\\stu\"")
}

3.4.2 多行字符串(原样字符串)

go 语言中要定义一个多行字符串时,使用 反引号 (即键盘左上角数字一左侧的那个按键) 包裹。也叫原样字符串,输入啥样,输出就啥样。

go 复制代码
package main

import (
	"fmt"
)

func main() {
	s := `
		床前明月光,
		疑是地上霜。
		举头望明月,
		低头思故乡。
	`
	fmt.Printf("%s \n", s)
}
go 复制代码
package main

import (
	"fmt"
)

func main() {
	s := `D:\Go\src\code.github.cnoeng\stu`
	// D:\Go\src\code.github.cnoeng\stu 
	fmt.Printf("%s \n", s)
}

3.4.3 字符串的常用操作

方法 含义
len(str) 获取字符串的长度
+ 或 fmt.Sprintf() 拼接字符串
strings.Split 分割
strings.contains 判断是否包含
strings.HasPrefixstrings.HasSuffix 前缀、后缀的判断
strings.Index()strings.LastIndex() 子串出现的位置
strings.Join(a[]string,sep string) join 操作 (拼接)

字符串是由 byte 字节组成,所以字符串的长度就是 byte 字节的长度。

go 复制代码
package main

import (
	"fmt"
	"strings"
)

func main() {
	s := `张三`
	// 6 
	fmt.Println(len(s))
	
	// 字符串拼接
	s1 := "李四"
	// fmt.Printf 只能输出到终端
	// 张三李四
	fmt.Printf("%s \n", s+s1)
	// 张三李四
	fmt.Printf("%s%s \n", s, s1)
	// fmt.Sprintf 可以将拼接后的值返回给变量
	s2 := fmt.Sprintf("%s%s \n", s, s1)
	// 张三李四
	fmt.Printf("%s \n", s2)

	// 字符串分割
	s3 := "/Users/cnpeng/CnPeng/04_Demos/12_Go"
	splitS := strings.Split(s3, "/")
	// [ Users cnpeng CnPeng 04_Demos 12_Go]
	fmt.Printf("%s \n", splitS)

	// 是否包含------true
	fmt.Println(strings.Contains(s2, "张三"))

	// 前缀和后缀------true
	fmt.Println(strings.HasPrefix(s2, "张"))
	// true
	fmt.Println(strings.HasSuffix(s2, "四"))

	// 子串位置------0
	fmt.Println(strings.Index(s2, "张"))
	// 9
	fmt.Println(strings.LastIndex(s2, "四"))

	// Join 拼接------+Users+cnpeng+CnPeng+04_Demos+12_Go
	fmt.Println(strings.Join(splitS, "+"))
}

3.4.4 byte 和 rune 类型

组成每个字符串的元素叫做字符。可以通过遍历或者单个获取字符串元素获得字符。字符使用单引号包裹,如:

go 复制代码
var a := '中'
var b := 'x'

go 语言中的字符有如下两种:

  • uint8 类型,或者叫 byte 类型,代表了 ASCII 码的一个字符。
  • rune 类型,代表一个 UTF-8 字符。一个 rune 字符由一个或多个 byte 组成。

当需要处理中文、日文或其他复合字符时,需要使用 rune 类型。rune 类型实际是一个 int32

go 复制代码
package main

import (
	"fmt"
)

func main() {
	s := "中国"

	// 普通遍历方式得到的是 byte ,最终输出结果为:228------ä184------¸173------­229------å155------›189------½
	for i := 0; i < len(s); i++ {
		fmt.Printf("%v------%c", s[i], s[i])
	}

	fmt.Println()

	// range 遍历得到的数 rune ,最终结果为:20013------中22269------国
	for _, c := range s {
		fmt.Printf("%v------%c", c, c)
	}
	fmt.Println()
}

因为 UTF-8 编码下一个中文汉字由 3-4 个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串,否则就会出现上面第一个遍历中的结果。

3.4.5 修改字符串

字符串是不能直接修改的。

字符串底层是一个 byte 数组,所以可以和 []byte 类型相互转换。

修改字符串时,需要先将其转换成 []rune[]byte, 修改完成后再转换为 string。无论哪种转换都会重新分配内存,并复制字节数组。

go 复制代码
package main

import (
	"fmt"
)

func main() {

	s1 := "big"
	byteS1 := []byte(s1)
	byteS1[0] = 'p'
	// pig
	fmt.Println(string(byteS1))

	s2 := "白萝卜"
	runeS2 := []rune(s2)
	runeS2[0] = '红'
	//红萝卜
	fmt.Println(string(runeS2))
}

3.5 类型转换和类型别名

3.5.1 类型转换

Go 语言中不允许隐式转换,所有类型转换必须显示声明,而且转换只能发生在两种相互兼容的类型之间。

go 复制代码
package main

func main() {
	var a byte = 97
	//显示类型转换
	var b int = int(a)
	
	//隐式类型转换,报错
	// var c int = a
	
	//类型不兼容,int 不能转为 bool
	//var d bool = bool(b)
	fmt.Println(d)
}

3.5.2 类型别名

  • 为现有的类型定义别名,方便调用。关键字 type

( 在 Swift 中也有这种类型别名,特别是对函数类型定义别名很有用)

go 复制代码
package main

import "fmt"

func main() {
	//1、为 int64 起一个类型别名为,bigint
	type bigint int64
	var x bigint = 100

	//2、同时定义多个类型别名
	type (
		myint int
		mystr string
	)

	var y myint = 11
	var z mystr = "12"

	fmt.Println(x, y, z)
	fmt.Printf("x,y,z 的类型分别为:%T , %T , %T \n ", x, y, z)
}

运行结果:

cnpeng$ go run Day1.go 
100 11 12
x,y,z 的类型分别为:main.bigint , main.myint , main.mystr 

3.6 strconv 包

Go 语言中 strconv 包实现了基本数据类型和其字符串表示的相互转换。主要有以下常用函数: Atoi()Itoa()parse 系列、format 系列、append 系列。

更多函数请查看官方文档。

3.6.1 string与int类型转换

这一组函数是我们平时编程中用的最多的。

3.6.1.1 Atoi()

Atoi() 函数用于将字符串类型的整数转换为int类型,函数签名如下。

go 复制代码
func Atoi(s string) (i int, err error)

如果传入的字符串参数无法转换为int类型,就会返回错误。

go 复制代码
s1 := "100"
i1, err := strconv.Atoi(s1)
if err != nil {
	fmt.Println("can't convert to int")
} else {
	fmt.Printf("type:%T value:%#v\n", i1, i1) //type:int value:100
}
3.6.1.2 Itoa()

Itoa() 函数用于将 int 类型数据转换为对应的字符串表示,具体的函数签名如下。

go 复制代码
func Itoa(i int) string

示例代码如下:

go 复制代码
i2 := 200
s2 := strconv.Itoa(i2)
fmt.Printf("type:%T value:%#v\n", s2, s2) //type:string value:"200"
3.6.1.3 a的典故

这是 C 语言遗留下的典故。C 语言中没有 string 类型而是用字符数组(array)表示字符串,所以 Itoa 对很多 C 系的程序员很好理解。

3.6.2 Parse系列函数

Parse 类函数用于转换字符串为给定类型的值:ParseBool()ParseFloat()ParseInt()ParseUint()

3.6.2.1 ParseBool()
go 复制代码
func ParseBool(str string) (value bool, err error)

返回字符串表示的 bool 值。

  • 当 str 为:1,t,T,TRUE,true,True 中的一种时为真值
  • 当 str 为:0,f,F,FALSE,false,False 中的一种时为假值
  • 其他输入内容一律返回 false
go 复制代码
fmt.Println(strconv.ParseBool("t"))
fmt.Println(strconv.ParseBool("TRUE"))
fmt.Println(strconv.ParseBool("true"))
fmt.Println(strconv.ParseBool("True"))
fmt.Println(strconv.ParseBool("0"))
fmt.Println(strconv.ParseBool("f"))
3.6.2.2 ParseInt()
go 复制代码
func ParseInt(s string, base int, bitSize int) (i int64, err error)

返回字符串表示的整数值,接受正负号。

  • base 指定进制(2到36),如果 base 为0,则会从字符串前置判断;0x 是16进制,0 是 8 进制,否则是 10 进制;

  • bitSize 指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64;

  • 返回的 err 是 *NumErr 类型的,如果语法有误,err.Error = ErrSyntax;如果结果超出类型范围 err.Error = ErrRange

3.6.2.3 ParseUnit()
go 复制代码
func ParseUint(s string, base int, bitSize int) (n uint64, err error)

ParseUint 类似 ParseInt 但不接受正负号,用于无符号整型。

3.6.2.4 ParseFloat()
go 复制代码
func ParseFloat(s string, bitSize int) (f float64, err error)

解析一个表示浮点数的字符串并返回其值。

如果 s 合乎语法规则,函数会返回最为接近 s 表示值的一个浮点数(使用 IEEE754 规范舍入)。

  • bitSize 指定了期望的接收类型,32 是 float32(返回值可以不改变精确值的赋值给float32),64 是 float64;
  • 返回值 err 是 *NumErr 类型的,语法有误的,err.Error=ErrSyntax;结果超出表示范围的,返回值 f 为 ±Inferr.Error= ErrRange
3.6.2.5 代码示例
go 复制代码
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64)
i, err := strconv.ParseInt("-2", 10, 64)
u, err := strconv.ParseUint("2", 10, 64)

这些函数都有两个返回值,第一个返回值是转换后的值,第二个返回值为转化失败的错误信息。

3.6.3 Format系列函数

Format 系列函数实现了将给定类型数据格式化为 string 类型数据的功能。

3.6.3.1 FormatBool()
go 复制代码
func FormatBool(b bool) string

根据 b 的值返回 "true""false"

3.6.3.2 FormatInt()
go 复制代码
func FormatInt(i int64, base int) string

返回 i 的 base 进制的字符串表示。base 必须在2到36之间,当 base 大于 10 时,结果中会使用小写字母 az 表示大于 10 的数字。

3.6.3.3 FormatUint()
go 复制代码
func FormatUint(i uint64, base int) string

是 FormatInt 的无符号整数版本。

3.6.3.4 FormatFloat()
go 复制代码
func FormatFloat(f float64, fmt byte, prec, bitSize int) string

函数将浮点数表示为字符串并返回。

  • bitSize 表示 f 的来源类型(32:float32、64:float64),会据此进行舍入。
  • fmt 表示格式:f(-ddd.dddd)、b(-ddddp±ddd,指数为二进制)、e(-d.dddde±dd,十进制指数)、E(-d.ddddE±dd,十进制指数)、g(指数很大时用e格式,否则f格式)、G(指数很大时用E格式,否则f格式)。
  • prec 控制精度(排除指数部分):feE,它表示小数点后的数字个数;对 gG,它控制总的数字个数。如果 prec 为 -1,则代表使用最少数量的、但又必需的数字来表示 f 。
3.6.3.5 代码示例
go 复制代码
s1 := strconv.FormatBool(true)
s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
s3 := strconv.FormatInt(-2, 16)
s4 := strconv.FormatUint(2, 16)

3.6.4 其他

3.6.4.1 isPrint()
go 复制代码
func IsPrint(r rune) bool

返回一个字符是否是可打印的,和 unicode.IsPrint 一样,r 必须是:字母(广义)数字标点符号ASCII空格

3.6.4.2 CanBackquote()
go 复制代码
func CanBackquote(s string) bool

返回字符串 s 是否可以不被修改的表示为一个单行的、没有空格tab之外控制字符反引号字符串

3.6.4.3 其他

除上文列出的函数外,strconv 包中还有 Append系列、Quote系列等函数。具体用法可查看官方文档。

更多函数请查看官方文档。

相关推荐
WaaTong4 分钟前
Java反射
java·开发语言·反射
Troc_wangpeng5 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的7 分钟前
解析json导出csv或者直接入库
开发语言·python·json
Envyᥫᩣ21 分钟前
C#语言:从入门到精通
开发语言·c#
齐 飞29 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
云空29 分钟前
《Python 与 SQLite:强大的数据库组合》
数据库·python·sqlite
暮毅34 分钟前
10.Node.js连接MongoDb
数据库·mongodb·node.js
wowocpp37 分钟前
ubuntu 22.04 server 格式化 磁盘 为 ext4 并 自动挂载 LTS
服务器·数据库·ubuntu
童先生42 分钟前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu43 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法