go语言学习笔记之一---基础类型

微笑转瞬即逝,但有时候,微笑背后的记忆却能永远长存

Posted by yishuifengxiao on 2020-09-13

一 命名

Go语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线。大写字母和小写字母是不同的:heapSortHeapsort是两个不同的名字。

命名规范:

1)字母、数字、下划线

2)不能以数字开头

3)名字不能是关键字

4) 区分大小写

Go语言中类似ifswitch的关键字有25个(均为小写)。关键字不能用于自定义名字,只能在特定语法结构中使用。

break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var

此外,还有大约30多个预定义的名字,比如inttrue等,主要对应内建的常量、类型和函数。

内建常量

true false iota nil

内建类型 :

int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error

内建函数 :

make len cap new append copy close delete
complex real imag
panic recover

二 变量

变量是几乎所有编程语言中最基本的组成元素,变量是程序运行期间可以改变的量。

从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间。

2.1 变量声明

Go语言的变量声明方式与C和C++语言有明显的不同。对于纯粹的变量声明, Go语言引入了关键字var,而类型信息放在变量名之后,示例如下:

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字:

1
var identifier type

可以一次声明多个变量:

1
var identifier1, identifier2 type

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
var a string = "Runoob"
fmt.Println(a)

var b, c int = 1, 2
fmt.Println(b, c)
}

变量申明的三个方法

1 第一种,指定变量类型,如果没有初始化,则变量默认为零值

1
2
var v_name v_type
v_name = value

零值就是变量没有做初始化时系统默认设置的值。

2 第二种,根据值自行判定变量类型。

1
var v_name = value

第三种,省略 var, 注意 \:=* 左侧如果没有声明新的变量,就产生编译错误,格式:*

1
v_name := value

2.2 变量初始化

对于声明变量时需要进行初始化的场景, var关键字可以保留,但不再是必要的元素,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var v1 int = 10 // 方式1

var v2 = 10 // 方式2,编译器自动推导出v2的类型

v3 := 10 // 方式3,编译器自动推导出v3的类型

fmt.Println("v3 type is ", reflect.TypeOf(v3)) //v3 type is int


//出现在 := 左侧的变量不应该是已经被声明过,:=定义时必须初始化

var v4 int

v4 := 2 //err

2.3 变量赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var v1 int

v1 = 123


var v2, v3, v4 int

v2, v3, v4 = 1, 2, 3 //多重赋值


i := 10

j := 20

i, j = j, i //多重赋值

2.4 匿名变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
_(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃:

_, i, _, j := 1, 2, 3, 4


func test() (int, string) {

return 250, "sb"

}

_, str := test()

匿名变量:丢弃数据不处理,匿名变量配合函数返回值使用,才有优势。

三 常量

在Go语言中,常量是指编译期间就已知且不可改变的值。常量可以是数值类型(包括整型、浮点型和复数类型)、布尔类型、字符串类型等。

常量的定义格式:

1
const identifier [type] = value

3.1 字面常量(常量值)

所谓字面常量(literal),是指程序中硬编码的常量,如:

1
2
3
4
5
6
7
8
9
123

3.1415 // 浮点类型的常量

3.2+12i // 复数类型的常量

true // 布尔类型的常量

"foo" // 字符串常量

3.2 常量定义

你可以省略类型说明符 [type],因为编译器可以根据变量的值来推断其类型。

  • 显式类型定义: const b string = "abc"
  • 隐式类型定义: const b = "abc"

多个相同类型的声明可以简写为:

1
const c_name1, c_name2 = value1, value2

示例代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值

area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}

运行结果为

1
2
面积为 : 50
1 false str

在定义常量组时,如果不提供初始值,则表示将使用上行的表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

const (
a = 1
b
c
d
)

func main() {
fmt.Println(a)
// b、c、d没有初始化,使用上一行(即a)的值
fmt.Println(b) // 输出1
fmt.Println(c) // 输出1
fmt.Println(d) // 输出1
}
  • 变量:程序运行期间,可以改变的量,变量声明需要var

  • 常量:程序运行期间,不可以改变的量,常量声明需要const

  • 常量可以使用自动推导赋值。不能使用 := 赋值

四 基础数据类型

4.1 分类

Go语言内置以下这些基础类型

类型 名称 长度 零值 说明
bool 布尔类型 1 false 其值不为真即为家,不可以用数字代表true或false
byte 字节型 1 0 uint8别名
rune 字符类型 4 0 专用于存储unicode编码,等价于uint32
int, uint 整型 4或8 0 32位或64位
int8, uint8 整型 1 0 -128 ~ 127, 0 ~ 255
int16, uint16 整型 2 0 -32768 ~ 32767, 0 ~ 65535
int32, uint32 整型 4 0 -21亿 ~ 21 亿, 0 ~ 42 亿
int64, uint64 整型 8 0
float32 浮点型 4 0.0 小数位精确到7位
float64 浮点型 8 0.0 小数位精确到15位
complex64 复数类型 8
complex128 复数类型 16
uintptr 整型 4或8 ⾜以存储指针的uint32或uint64整数
string 字符串 “” utf-8字符串

go 1.9版本对于数字类型,无需定义int及float32、float64,系统会自动识别

4.2 布尔类型

在 Go 中,布尔值的类型为 bool,值是 true 或 false,默认为 false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var v1 bool

v1 = true

v2 := (1 == 2) // v2也会被推导为bool类型


//布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换

var b bool

b = 1 // err, 编译错误

b = bool(1) // err, 编译错误

4.3 整 型

1
2
3
4
5
var v1 int32

v1 = 123

v2 := 64 // v1将会被自动推导为int类型

4.4 浮点型

1
2
3
4
5
var   f1 float32

f1 = 12

f2 := 12.0 // 如果不加小数点, fvalue2会被推导为整型而不是浮点型,float64

4.5 字符类型

在Go语言中支持两个字符类型,一个是byte(实际上是uint8的别名),代表utf-8字符串的单个字节的值;另一个是rune,代表单个unicode字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
)

func main() {

var ch1, ch2, ch3 byte

ch1 = 'a' //字符赋值

ch2 = 97 //字符的ascii码赋值

ch3 = '\n' //转义字符

fmt.Printf("ch1 = %c, ch2 = %c, %c", ch1, ch2, ch3)

}

4.6 字符串

在Go语言中,字符串也是一种基本类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var str string // 声明一个字符串变量

str = "abc" // 字符串赋值

ch := str[0] // 取字符串的第一个字符

fmt.Printf("str = %s, len = %d\n", str, len(str)) //内置的函数len()来取字符串的长度

fmt.Printf("str[0] = %c, ch = %c\n", str[0], ch)

//`(反引号)括起的字符串为Raw字符串,即字符串在代码中的形式就是打印时的形式,它没有字符转义,换行也将原样输出。

str2 := `hello

mike \n \r测试

`

fmt.Println("str2 = ", str2)

4.7 复数类型

复数实际上由两个实数(在计算机中用浮点数表示)构成,一个表示实部(real),一个表示虚部(imag)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var v1 complex64 // 由2个float32构成的复数类型

v1 = 3.2 + 12i

v2 := 3.2 + 12i // v2是complex128类型

v3 := complex(3.2, 12) // v3结果同v2

fmt.Println(v1, v2, v3)

//内置函数real(v1)获得该复数的实部

//通过imag(v1)获得该复数的虚部

fmt.Println(real(v1), imag(v1))

五 fmt包的格式化输出输入

5.1 格式说明

格式 含义
%% 一个%字面量
%b 一个二进制整数值(基数为2),或者是一个(高级的)用科学计数法表示的指数为2的浮点数
%c 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
%d 一个十进制数值(基数为10)
%e 以科学记数法e表示的浮点数或者复数值
%E 以科学记数法E表示的浮点数或者复数值
%f 以标准记数法表示的浮点数或者复数值
%g 以%e或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出
%G 以%E或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出
%o 一个以八进制表示的数字(基数为8)
%p 以十六进制(基数为16)表示的一个值的地址,前缀为0x,字母使用小写的a-f表示
%q 使用Go语法以及必须时使用转义,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字
%s 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符)
%t 以true或者false输出的布尔值
%T 使用Go语法输出的值的类型
%U 一个用Unicode表示法表示的整型码点,默认值为4个数字字符
%v 使用默认格式输出的内置或者自定义类型的值,或者是使用其类型的String()方式输出的自定义值,如果该方法存在的话
%x 以十六进制表示的整型值(基数为十六),数字a-f使用小写表示
%X 以十六进制表示的整型值(基数为十六),数字A-F使用小写表示

5.2 输出

%c 以字符方式打印

%d 以整形方式打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//整型
a := 15

fmt.Printf("a = %b\n", a) //a = 1111

fmt.Printf("%%\n") //只输出一个%

//字符

ch := 'a'

fmt.Printf("ch = %c, %c\n", ch, 97) //a, a

//浮点型

f := 3.14

fmt.Printf("f = %f, %g\n", f, f) //f = 3.140000, 3.14

fmt.Printf("f type = %T\n", f) //f type = float64

//复数类型

v := complex(3.2, 12)

fmt.Printf("v = %f, %g\n", v, v) //v = (3.200000+12.000000i), (3.2+12i)

fmt.Printf("v type = %T\n", v) //v type = complex128

//布尔类型

fmt.Printf("%t, %t\n", true, false) //true, false

//字符串

str := "hello go"

fmt.Printf("str = %s\n", str) //str = hello go

5.3 输人

1
2
3
4
5
6
7
8
9
var v int

fmt.Println("请输入一个整型:")
//会阻塞用户的输入
fmt.Scanf("%d", &v)

//fmt.Scan(&v)

fmt.Println("v = ", v)

六 类型转换

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

1
2
3
4
5
var ch byte = 97

//var a int = ch //err, cannot use ch (type byte) as type int in assignment

var a int = int(ch)

七 类型别名

1
2
3
4
5
6
7
8
9
10
11
12
   type     bigint int64 //int64类型改名为bigint

var x bigint = 100


type (

myint int //int改名为myint

mystr string //string改名为mystr

)

八 运算符

运算符 术语 示例 说明
& 取地址运算符 &a 变量a的地址
* 取值运算符 *a 指针变量a所指向内存的值
1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
a := "aaa"
fmt.Println(" a =", a)
fmt.Println(" &a =", &a)
fmt.Println(" *&a =", *&a)
// 下面这一行会报错 invalid indirect of a (type string)
//fmt.Println(" *a =", *a)
}