第二节 Go语言基础语法(一)

 

go的变量、关键字、常量与枚举、一点点基础知识补充

与其说是教程,更像是总结

一起学习:smiley:


1. 变量的定义

go语言的变量定义与其他语言(c,cpp,java…)不太一样,这个需要适应一下

下面主要以一个个小实列来解释说明,不会是全部说明,也做不到全部说明(全部说明那叫官方文档:joy:)​

这里创建一个文件夹test(名称随意),

在文件夹中创建一个文件main.go(名称随意)

1.1 自定义和使用Var关键字

单变量定义

package main

import "fmt"

func variableZeroValue() {
	//像数据库的变量定义
	var a int //默认为0
	var s string
	//空串会输出类似一个空格
	fmt.Println(a, s, a)
	fmt.Println(a, a)
	//%s会输出内容,%q会输出引号包裹内容
	fmt.Printf("%d,%q,%s\n", a, s, s)
	s = "hello"
	fmt.Printf("%d,%q,%s\n", a, s, s)
}

func main() {
	variableZeroValue()
}

运行程序

1.打开终端 Ctrl+Shift+`

2.在终端中输入下面指令, 其中main(是你自己设置的文件名称)

go run main.go

3.查看输出结果展示

下面都不在重复如何运行程序啦

继续继续

多变量定义

func variableInitialValue() {
	//像数据库的多变量定义
	var a, b int = 3, 4
	var s string = "abc"
	//空串会输出类似一个空格
	fmt.Println(a, s, b)
	fmt.Println(a, b)
	//%s输出内容,%q会输出引号包裹内容
	fmt.Printf("%d,%q,%s\n", a, s, s)
}

运行结果:

PS F:\Desktop\test> go run main.go
3 abc 4
3 4        
3,"abc",abc

全局变量定义

在go语言的规则中,只有var能定义全局的变量,为什么是”只有”,因为后面还有其他便捷的定义方式。

还有,不知道你发现了go语言的严格没有,go的变量定义了必须使用,不然就给你报错,编译都过不了,还有一点你可能没发现,那就是变量名称的大小写,这个以后会说明的(挖点坑)。

下面是定义全局变量

package main

import "fmt"

var aa = 3
var bb = 4

var (
	cc = 3
	dd = 3
	ee = "hello"
)

func main() {
	fmt.Println(aa, bb, cc, dd, ee)
}
PS F:\Desktop\test> go run main.go
3 4 3 3 hello

嘿嘿,不知道你发现上面的例子没写具体类型了没有,接着往后看看

让编译器自动觉定类型

弱类型定义数据

那强类型是啥?

强类型就是var a int = 3 ,我直接告诉它我就要int型,这种定义方式就是强类型,下面是弱类型的案例代码:

func variableTypeDedution() {
	//弱类型定义数据
	var a, b, c, d = 3, 4, true, "abc"
	fmt.Println(a, b, c, d)
}

冒号赋值 :sparkles:

这个定义变量时就方便很多了,那也许你会好奇,第一,那我怎么知道它自动转换成了啥类型呢?第二,我不想要他的类型怎么办?

下面案例会给出答案

func variableShorter() {
	//冒号赋值
	a, b, c, d := 3, 4, true, "abc"
	b = 5
	fmt.Println(a, b, c, d)
    //输出变量的类型,解决第一个问题
    fmt.Printf("b type:%T\n", b)
    fmt.Printf("c type:%T\n", c)
    fmt.Printf("d type:%T\n", d)
    //强制类型转换,解决第二个问题
    b = (float)b
    fmt.Printf("b type:%T\n", int64(b))
}

运行上面两个函数的结果:

PS F:\Desktop\test> go run main.go
3 4 true abc
3 5 true abc 
b type:int   
c type:bool  
d type:string
b type:int64 

1.2 需要注意的细节

默认值

整型和浮点型变量默认值:0

字符串默认是空串

布尔值默认是false

函数、指针变量、切片默认值为nil(后面会讲的)

特殊值

int unit uintptr 大小取决于平台

别名

后面讲的

byte == UTF-8单字节 uint8别名

rune == unicode 4字节 int32别名

通用打印输出

常用打印

  1. %v 只输出所有的值
  2. %+v 先输出字段类型,再输出该字段的值
  3. %#v 先输出结构体名字值,再输出结构体(字段类型+字段的值)
  4. %T 输出变量的类型

整型打印

%5d , 123 = [ 123]

%05d , 123 = [00123]

字符串打印

%s,”hello” = [hello]

%q,”hello” = [“hello”] 会带双引号括起来

2. go的25个保留关键字

go和其他语言不太相同,它只有25个关键字,如下:

包管理2):
	import	package

程序实体声明与定义8):
	chan	const	func	interface	map	struct	type	var

程序流程控制15):
	break	case	continue	default	defer	else	fallthrough	
	for		go		goto		if		range	return	select		switch

这些关键字大部分都是常用的,后面也都会使用到,这里推荐一篇讲的比较全的一篇文章

3. go语言的基本数据类型

Go语言的基本类型有:

注意,没有char类型

  • bool
  • string
  • int、int8、int16、int32、int64
  • uint、uint8、uint16、uint32、uint64、uintptr
  • byte // uint8 的别名
  • rune // int32 的别名 代表一个 Unicode 码
  • float32、float64
  • complex64、complex128

说明一下complex64

这个一般用不到的,了解一下:

complex64 = 实部(float32) + 虚部(float32) complex128 = 实部(float64) + 虚部(float64)

上面所列举的都开始不需要就全部掌握,了解几个常用的就可以,后面会慢慢使用到的

4. 总结小案例

那来验证一下伟大的欧拉公式,再强调一下啊,是验证不是证明。

下面是从百度百科复制来的定义

package main

import (
	"fmt"
	"math"
	"math/cmplx"
)

func eular() {
	/*
		原始的定义方式
		var x complex128 = complex(1, 2) // 1+2i
		var y complex128 = complex(3, 4) // 3+4i
	*/
	//偷懒
	c := 3 + 4i
	//求模,也就是求绝对值(不准确,方便理解)
	println(cmplx.Abs(c)) //+5.000000e+000
	//证明欧拉公式,1i就是虚数的i
	println(cmplx.Pow(math.E, 1i*math.Pi) + 1)
    //(0.000+0.000i)
	fmt.Printf("%.3f\n", cmplx.Exp(1i*math.Pi)+1) 
}

func main() {
	eular()
}

输出结果:

PS F:\Desktop\test> go run main.go
+5.000000e+000
(+0.000000e+000+1.224647e-016i)
(0.000+0.000i)

验证通过:joy:

5. 常量与枚举

5.1 常量

go语言中常量一般不会大写(对比其他语言来说的),因为大小写在go语言中有其他的含义(后面会说)

下面是常量的使用:

//定义在函数外
const c = 5

func consts() {
	//定义在函数内
	const (
		fileName = "abc.txt"
		a, b     = 3, 4
	)

	var c int
	//const的本质就是固定的文本,所以编译器可以帮忙处理类型转换
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println("c= ", c, fileName)
}

5.2 枚举

直接上代码案例,核心是对iota的理解,可以理解为一颗种子,它在枚举中的用法比较丰富

package main

import (
	"fmt"
)

func enums() {
	//普通枚举定义
	const (
		z = 0
		x = 1
		c = 2
		v = 3
	)

	const (
		//iota表示自增值种子(从0开始)
		// _ 跳值
		cpp = iota
		java
		python
		_
		goland
	)

	//iota位掩码表达式
	const (
		IgEggs         = 1 << iota // 1 << 0 which is 00000001
		IgChocolate                // 1 << 1 which is 00000010
		IgNuts                     // 1 << 2 which is 00000100
		IgStrawberries             // 1 << 3 which is 00001000
		IgShellfish                // 1 << 4 which is 00010000
	)

	//iota定义数量级
	const (
		b = 1 << (10 * iota)
		kb
		mb
		gb
		tb
		pb
	)

	fmt.Println(z, x, c, v)
	fmt.Println(cpp, goland, python, java)
	fmt.Println(IgEggs, IgChocolate, IgNuts, IgStrawberries, IgShellfish)
	fmt.Println(b, kb, mb, gb, tb, pb)
}

func main() {
	enums()
}

输出结果:

PS F:\Desktop\test> go run main.go
0 1 2 3
0 4 2 1
1 2 4 8 16
1 1024 1048576 1073741824 1099511627776 1125899906842624

5.3 需要注意的细节

注意,go语言的枚举不想其他语言,不使用itoa只有const就是在定义普通的变量,只是长得向枚举类型,使用itoa后才有枚举效果(个人的简单理解)

枚举 const

const(
	a = 0
	b = 1
	c = 2
)

a,b,c -> 0,1,2
const(
	a = 10
	b
	c
)

a,b,c -> 10,10,10

种子 iota(自增器)

const(
	a = itoa
	b = itoa
	c = itoa
)

a,b,c -> 0,1,2
const(
	a = itoa
	b
	c
)

a,b,c -> 0,1,2

6. 基础知识补充

6.1 常见运算符

A = 0011 1100 【60】
B = 0000 1101 【13】

A&B = 0000 1100 同1为1
A|B = 0011 1101 遇1为1
A^B = 0011 0001 不同为1

<< 左移 
A << n == A * 2^n
A << 2 == A * 4 == 60 * 4 == 240 == 1111 0000

>> 右移
A >> n == A / 2^n
A >> 2 == A / 4 == 60 / 4 == 15  == 0000 1111

6.2 二进制运算符

//测试输出
var n int
//输出一个整数的二进制
for i := 0; i < int(unsafe.Sizeof(n)); i++ {
   fmt.Print(60 >> i & 1) 
}
//输出一个整数的二进制
fmt.Printf("\n%b", 60) 

结果输出:

PS F:\Desktop\test> go run main.go
00111100
111100