Golang 学习笔记 004 基础数据类型及输出格式化标记

只谈情不闲聊 提交于 2020-01-08 21:29:21

数据类型-基础数据类型

Go 语言中包含的数据类型有以下几种:
  • 基础类型 

    • 布尔型 bool : 值只可以是常量 true 或者 false
    • 字符串 string : 由一串固定长度的字符连接起来的字符序列
    • 整数
      • 有符号整数
        • int : 在 32 位系统上通常为 32 位宽,在 64 位系统上则为 64 位宽
        • int8 : 有符号 8 位整型 (-128 到 127)
        • int16 : 有符号 16 位整型 (-32768 到 32767)
        • int32 : 有符号 32 位整型 (-2147483648 到 2147483647)
        • int64 : 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
      • 无符号整数
        • uint : 在 32 位系统上通常为 32 位宽,在 64 位系统上则为 64 位宽
        • uint8 : 无符号 8 位整型 (0 到 255)
        • uint16 : 无符号 16 位整型 (0 到 65535)
        • uint32 : 无符号 32 位整型 (0 到 4294967295)
        • uint64 : 无符号 64 位整型 (0 到 18446744073709551615) 
      • 特殊整型
        • uintptr : 无符号整型,用于存放一个指针。在32位系统上通常为32位宽,在64位系统上则为64位宽
        • byte : uint8 的别名, 表示一个 ascii 字符
        • rune : int32 的别名, 表示一个 Unicode 码点
    • 浮点型
      • float32 : 32位浮点型数
      • float64 : 64位浮点型数
    • 复数型
      • complex64 : 实部和虚部都是float32
      • complex128 : 实部和虚部都是float64
  • 派生类型

    • 数组 : array
    • 切片 : slice
    • 字典 : map
    • 通道 : channel
    • 函数 : funciton
    • 结构体 : struct
    • 接口 : interface
    • 指针 : pointer

本节只介绍基础数据类型

布尔类型 bool

go 中以 bool 关键字声明布尔类型的变量,布尔类型的值只可以是常量 true 或者 false。
需要注意:

  • 布尔类型变量的默认值为 false
  • 布尔类型无法与其他类型进行转换,例如:不允许将整型强制转换为布尔类型,反之亦然
  • 布尔类型无法参与述职运算
var a bool = true

字符串类型 string

go 中的 string 类型为原生类型,内部实现使用的是 utf-8 编码。字符串需要使用双引号。

str1 := "hello world"
str2 := "你好世界"

转义字符

转义符含义
\a 响铃
\b 退格
\f 换页
\n 换行
\r 回车
\t 制表符
\v 垂直制表符
\' 单引号 (只用在 '\'' 形式的rune符号面值中)
\" 双引号 (只用在 "..." 形式的字符串面值中)
\\ 反斜杠
func main() {
    var words string = "Hello \nworld!"
    fmt.Println(words)
}

结果:
shell
$ go run hello.go 
Hello 
world!

单引号、双引号和反引号

  • 单引号:用于表示 rune 类型,一个用于表示 unicode 代码点的整数值,和其他语言的 byte类似,但又不完全一样,引号中的内容代表字符本身的 unicode 值。
  • 双引号:表示一个字符串,支持转义,但不支持多行
  • 反引号:表示一个字符串,支持多行,但不支持转义
func main() {
    var words string = "Hello \n world!"
    var words2 string = `你好
中国`
    fmt.Println(words)
    fmt.Println(words2)
}

结果

$ go run hello.go 
Hello 
 world!
你好
中国

字符串操作

字符串操作内容较多,后面单列一节。

整数

intint8int16int32int64
uint uint8 uint16 uint32 uint64

整数有如上几种,只要记住不同长度的整数使用不用的类型即可,需要注意的是,int 和 uint 在不同平台上表现会不同。

字面量

在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法。整数、浮点数以及字符串等等都是字面量。字面量就是没有用标识符封装起来的量,是“值”的原始状态。

var age int = 12 // 12 是字面量
var name string = "resn"  // resn是字面量

不同进制的表示方法

从 1.13 开始,go开始支持表示二进制数字和八进制数字

进制表示方法示例
二进制 使用前缀0b或0B来表示二进制数 0b1010
八进制 使用前缀0o或0O来表示八进制数 0o11
十六进制 使用前缀0x或0X来表示十六进制数 0x1a

另外需要了解的一个知识点:
在表示一个很大的数字的时候,我们一般使用科学计数法e,例如220000 可以表示为2.2e+5。在十六进制中,也有一个计数法 p,0x十六进制整数部分.十六进制小数部分p指数,如果 p 之前的十六进制书为 a,指数为 b,那么实际的数字就是:a*(2的b次幂)。
科学计数法里的 e 表示的是 10, 这里的 p 表示的 2。

    num_b := 0b1010 // 二进制
    num_o := 0o12   // 八进制
    num_h := 0x2A   // 十六进制

    fmt.Println("十进制", num_b)  // 打印结果为十进制的值
    fmt.Println("十进制", num_o)  // 打印结果为十进制的值
    fmt.Println("十进制", num_h)   // 打印结果为十进制的值

    var num int = 100
    fmt.Printf( "二进制 %b \n", num)   // 打印二进制值
    fmt.Printf( "八进制 %o \n", num)   // 打印八进制值
    fmt.Printf( "十进制 %d \n", num)   // 打印十进制值
    fmt.Printf( "十六进制 %x \n", num)  // 打印十六进制值
    fmt.Printf( "十六进制 %X \n", num)  // 打印十六进制值
    
    fmt.Println(2.2e+5)    // 科学计数法 220000
    fmt.Println(0x1p-2)    // 表示十六进制的 1 乘以 2 的 -2 次幂 ,结果为十进制的 0.25
    fmt.Println(0x1p2)     // 表示十六进制的 1 乘以 2 的 2 次幂,结果为十进制的 4
    fmt.Println(0x0.1p0)   // 表示十六进制的 0.1乘以 2 的 0 次幂,十六进制的 0.1 相当于十进制的1/16(0.0625), 结果为 0.0625

特殊整型

uintptr
byte
rune

作为 golang 的内置类型,uintptr 是一个无符号的整型,用于存储指针,可以做必要的指针数值计算。 常和unsafe.Pointer配合,用于指针计算。

组成字符串的元素叫做字符,在golang 中,byte 和 rune 都用来表示字符,区别是:

  • byte:unit8,表示一个 ascii 字符,一个字节
  • rune:int32,表示一个 utf-8 字符,四个字节 在处理字符时,如果字符属于 ascii,byte 和 rune 都可以使用,但字符中含有中文或者其他非 ascii 字符时,就要用 rune 来表示, 
    var name1 byte = '中'    // 报错: constant 20013 overflows byte
    fmt.Printf("%v %c \n", name1, name1) 
    
    var name2 rune = '中'    // 输出: 20013 中 
    fmt.Printf("%v %c \n", name2, name2)
    
    var name3 byte = 'A'    // 输出: 65 A
    fmt.Printf("%v %c \n", name3, name3)
    
    var name4 rune = 'A'    // 输出: 65 A
    fmt.Printf("%v %c \n", name4, name4)

浮点型

float32
float64

浮点型有两种,float32 和 float64 ,其中 float32 最大值约为 3.4e+38
,可直接使用常量math.MaxFloat32;float64值约为 1.8e+308,可使用使用常量 math.MaxFloat64 。

fmt.Println(math.MaxFloat32)
fmt.Println(math.MaxFloat64)

复数型

complex64
complex128

我们把形如z=a+bi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位。当z的虚部等于零时,常称z为实数;当z的虚部不等于零时,实部等于零时,常称z为纯虚数。
golang 中使用 complex64 和 complex64 表示复数。

complex64 : 实部和虚部都是 32 位。
complex128 : 实部和虚部都是 64 位。

在 golang 中有两中方式构造复数:

    c1 := complex(1,2) // 第一种:使用 complex 函数
    c2 := 3+4i         // 第二种:直接定义
    fmt.Println(c1)    // 结果为:(1+2i)
    fmt.Println(c2)    // 结果为:(3+4i)
    fmt.Println(c1 + c2)   // 结果为:(4+6i)
    fmt.Println(c1 * c2)   // 结果为:(-5+10i)

类型转换

在 golang 中,没有类型的隐式转换,把一个类型转换为另一个类型只能强制转换。
强制转换的语法如下:
T(v) : T 是新类型,v 是原有类型,即这里的 v 会被转换为 T 类型。

    // 计算圆形周长
    var r int = 12
    var PI float64 = 3.14
    l := 2 * PI * r
    fmt.Println(l)

上面的代码会报错:invalid operation: 2 * PI * r (mismatched types float64 and int), 如果我们行正常运行程序就需要做强制类型转换。

    // 计算圆形周长
    var r int = 12
    var PI float64 = 3.14
    l := 2  * PI * float64(r)
    fmt.Println(l)

fmt.printf 的格式化占位符

fmt 包的主要用途是格式化字符串,前面我们已经用到了其中的打印函数。这里在在做一个简单介绍:

fmt.print

属于标准输出流,一般使用它来进行屏幕输出.内容输出后不会换行

fmt.println

输出内容,最后会增加一个换行。

fmt.printf

使用各种占位符进行格式化输出,占位符有如下内容:

//定义一个是 struct ,方便举例
type Human struct {
    name string
    age int
}
var people = Human{name:"resn", age:12}
......

普通占位符

占位符说明
%v 对应值的默认格式。
%+v 打印结构体时,会添加字段名
%#v 对应值的Go语法表示
%T 对应值的类型的Go语法表示
%% 打印出百分号
//示例
fmt.Printf("%v \n", people)     // 输出结果:{resn 12} 
fmt.Printf("%+v \n", people)    // 输出结果:{name:resn age:12} 
fmt.Printf("%#v \n", people)    // 输出结果:main.Human{name:"resn", age:12} 
fmt.Printf("%T \n", people)     // 输出结果:main.Human 
fmt.Printf("%% \n")             // 输出结果:%

布尔占位符

占位符说明
%t 输出true 或 false
//示例
fmt.Printf("%t \n",true)    // 输出结果:true
fmt.Printf("%t \n",false)   // 输出结果:false

整数占位符

占位符说明
%b 二进制的值
%c 对应Unicode码点所表示的字符
%d 十进制的值
%o 八进制的值
%q 单引号围绕的字符字面值,由Go语法安全地转义
%x 十六进制的值,字母形式为小写 a-f
%X 十六进制的值,字母形式为大写 A-F
%U Unicode格式:U+1234,等同于 "U+%04X"
//示例
fmt.Printf("%b \n", 15)                       // 输出结果:1111
fmt.Printf("%c %c\n", 0x4e2d, 0x56fd)         // 输出结果:中 国
fmt.Printf("%d %d \n", 0x4e2d, '国')          // 输出结果:20013 22269 
fmt.Printf("%o %o %o\n", 0x4e2d, '国', 16)    // 输出结果:47055 53375 20
fmt.Printf("%q %q \n", 0x4e2d, 22269, )       // 输出结果:'中' '国'
fmt.Printf("%x %x \n", "中",  24)             // 输出结果:e4b8ad 18
fmt.Printf("%X %X \n", "中",  24)             // 输出结果:E4B8AD 18
fmt.Printf("%U \n", 15)                       // 输出结果:U+000F 

浮点数和复数的组成部分(实部和虚部)

占位符说明
%b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 的 'b' 转换格式一致。例如 -123456p-78
%e 科学计数法,例如 -1234.456e+78
%E 科学计数法,例如 -1234.456E+78
%f 有小数点而无指数,例如 123.456
%g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)
%G 根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的0)

对于 %g和%G 而言,精度为所有数字的总数,例如:233.33,%.4g 会打印123.5,而 %5.2f 会打印233.33。
%e 和 %f 的默认精度为6

//示例
fmt.Printf("%b \n", 12)         //  输出结果:1100
fmt.Printf("%e \n", 20.2)       //  输出结果:2.020000e+01
fmt.Printf("%E \n", 20.2)       //  输出结果:2.020000E+01
fmt.Printf("%f \n", 20.2)       //  输出结果:20.200000
fmt.Printf("%g \n", 20.20)      //  输出结果:20.2
fmt.Printf("%G \n", 20.20+20i)  //  输出结果:(20.2+20i) 

字符串与字节切片

占位符说明
%s 输出字符串表示(string类型或[]byte)
%q 双引号围绕的字符串,由Go语法安全地转义
%x 十六进制,小写字母,每字节两个字符
%X 十六进制,大写字母,每字节两个字符
//示例
fmt.Printf("%s \n", []byte("中华民族")) //  输出结果:中华民族 
fmt.Printf("%q \n", "中华民族")         //  输出结果:"中华民族"
fmt.Printf("%x \n", "resn")             //  输出结果:7265736e
fmt.Printf("%X \n", "resn")             //  输出结果:7265736E

指针

占位符说明
%p 十六进制表示,前缀 0x
var people = Human{name:"resn", age:12}
fmt.Printf("%p", &people)   // 输出结果: 0xc00008a020

其他标记

占位符说明
+ 始终打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符。 
- 在右侧而非左侧填充空格(左对齐该区域)
# 备用格式:为八进制添加前导 0(%#o);为十六进制添加前导 0x(%#x)或 0X(%#X),为 %p(%#p)去掉前导 0x;如果可能的话,%q(%#q)会打印原始 (即反引号围绕的)字符串;如果是可打印字符,%U(%#U)会写出该字符的Unicode 编码形式(如字符 x 会被打印成 U+0078 'x')。
‘ ’ (空格)为数值中省略的正负号留出空白(% d);
0 填充前导的0而非空格;对于数字,这会将填充移到正负号之后
fmt.Printf("%+q \n", "中华民族")            //  输出结果:"\u4e2d\u534e\u6c11\u65cf" 
fmt.Printf("|%-6.2f|%-6.2f| \n",12.2,3.33) //  输出结果:|12.20 |3.33  | 
fmt.Printf("%#U \n", 'A')                  //  输出结果:U+0041 'A' 
fmt.Printf("% x \n", "中华民族")            //  输出结果:e4 b8 ad e5 8d 8e e6 b0 91 e6 97 8f 
fmt.Printf("%0d \n", 22)                    //  输出结果:22 

其他注意事项:

//最小宽度为6,默认右对齐,不足6位时,空格补全,超过6位时,不会截断
fmt.Printf("|%6d|%6d|\n",12,1234567) // |    12|1234567|
 
//最小6个宽度(包含小数点),2位小数,超过6位时,不会截断
fmt.Printf("|%6.2f|%6.2f|\n",12,222.333) // |%!f(int=    12)|222.33|
 
//使用 - 表示左对齐
fmt.Printf("|%-6.2f|%-6.2f|\n",12.2,3.33) //|12.20 |3.33  |   
 
//最小6个宽度,右对齐,不足6个时,空格补齐,超过6位时,不会截断
fmt.Printf("|%6s|%6s|\n","foo","abcdefgg") //|   foo|abcdefgg|
 
////最小6个宽度,右对齐,不足6个时,空格补齐,超过6位时,不会截断
fmt.Printf("|%-6s|%-6s|\n","foo","abcdeefgth") //|foo   |abcdeefgth|





易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!