1、Golang基础--Go简介、环境搭建、变量、常量与iota、函数与函数高级

2023-07-11,,

1 Go语言介绍

1 golang--》Go---》谷歌公司 2009年
golang:指go语言,指的go的sdk
goland:软件,ide:集成开发环境 Java写的
2 Go是静态强类型语言
静态:需要编译再执行
C、C#、Java:编译成不同平台的可执行文件在不同平台执行
c语言:编译慢
Go:编译快、并且可跨平台编译
动态:python php nodejs
需要一个解释器
边解释边运行
对运维很麻烦
pyinstaller 弄成可执行文件
强类型:
不同类型之间不允许直接运算(所以要强制类型转换)
go如何强制类型转换:显式类型转换
Java:可以字符串+数字 但是是强类型语言--隐式类型转换、内部自动转换
弱类型:js
比如可以:字符串+数字
3 Go语言特性
跨平台的编译型语言(交叉编译)
语法接近C语言
管道(channel),切片(slice),并发(routine)--》线程池+协程
有垃圾回收的机制(GC机制)
支持面向对象和面向过程的编程模式
(继承,封装,多态)写法有点古怪
4 Go语言发展(版本/特性)
// go语言也是用c写的
//java,python都是用c写的
2012年3月28日 go1 —— 稳定版版的发布
2015年8月19日 go1.5 —— 实现的架构变化,同时保留了和旧版本的兼容性,本次更新中移除了”最后残余的C代码”---》自举
2018年8月24日 go1.11 —— modules支持,摒弃掉go path的包管理
2020 年 2 月 go 1.14— — 现在 Go Module 已经可以用于生产环境
至今:1.17.6 开始支持泛型(额外操作) 5 go应用领域
-服务端开发 高并发
-微服务方向
-区块链开发 第一款开源的区块链软件是用go写的
-自动化运维 docker,k8s二开(docker、k8s是go写的,对go友好)
-云平台
-各个互联网公司都会招go开发
-中小型公司跟风
-前景:很广阔
-以后自身有很好的未来:python、go、java(热门语言)都要会
-go简单易学

2 静态和动态语言

c语言:按照c的语法写代码---->把源代码拿到Linux机器编译--》编译成Linux的可执行文件---》在Linux平台运行
java:一处编码处处运行,编译型语言
-java的编译不是编译成可执行文件----》字节码文件,jar,war---》不能直接运行在操作系统之上(不是可执行文件)
-java虚拟机:不同平台有不同平台的虚拟机,字节码文件运行在虚拟机之上
-java的跨平台本质是不同平台装了不同平台的虚拟机---》有的人把它当成解释器
python:解释型----》python的源代码,运行在不同平台的解释器之上----》天然跨平台 php:解释型:php的解释器
nodejs: node环境 go:编译型,交叉编译(跨平台编译),只需要拿到编译好的可执行文件,直接运行即可

3 go开发环境搭建

// 搭建开发环境
// go的运行环境:不需要搭建---》可执行文件 // go的sdk----》内置函数,包,编译go源码(编译成可执行文件)
-1.17 最新 ,向下兼容
-下载地址:https://golang.google.cn/dl/
-go1.17.6.windows-amd64.msi 一路下一步
-安装完成后,会把安装路径加入到环境变量
-go 命令,可以找到(如果没有装sdk,go可执行文件是没有的) // 集成开发工具:推荐 goland
-goland:推荐,收费,免费试用30天,老版本可以卡bug,无限试用30天
-学生免费(教育邮箱)
-开源软件作者免费(github开源持续多长时间提交代码)
-花钱:单软件,多软件授权,多账号
-破解:pycharm如何破,这个一样
-下载地址:
-https://www.jetbrains.com/zh-cn/go/download/other.html---》2021.1--》好破解
-goland,pycharm,webstorm。。一家公司出的 Jetbrains
-快捷键都一样,使用习惯都一样
-安装:一路下一步
-vs code
-免费,有部分公司用,不涉及到版权问题
-vim
-装各种插件 // 验证环境搭建
-打开cmd创建,输入
-go version // 查看版本信息
-go env // 查看go的环境变量

4 第一个go程序

// 新建的go项目内,有go.mod 文件,后面会讲,做包管理的

// 代码写好---》go是编译型语言----》编译成可执行文件----》运行可执行文件
// 运行方法:
- go build go文件名字 // 编译go文件,编译成 go文件名字.exe
- go文件名字.exe 可执行文件运行即可 // 开发阶段----》编译--》运行,比较麻烦,所以:
-goland提供了,编译并运行---》右键---》run
-原生提供了一个命令 (编译并运行的命令),但是编译后的文件,不在项目根路径下
-go run go文件名字 // ************第一个helloworld的代码*********** package main // 指定包名,任何一个go文件都要有这句话,包名可以不一样,目前必须叫main import "fmt" //导入内置包,fmt包,只要使用了fmt包,会自动导入,goland自动导入的,如果其他编辑器,需要手动导入 func main() { // 定义一个函数,函数名叫 main,目前必须叫main
fmt.Println("hello world") // 真正的在控制台输出 hello world,必须用双引号
} // 第一行,必须指定是main包
// 需要导入fmt包
// 程序要运行,必须写一个main函数,在main函数中打印helloworld // 注意:go的项目入口:必须是main包下的main函数 // fmt.Println(a...) 是 goland给提示的东西,其实根本不存在,函数的参数提示,不用关注

5 语法和命名规范

// 第一行必须是包名
// 程序要运行,必须是main包下的main函数
-一个项目中有一个main包,有两个main函数,它就不能运行,以后写项目肯定不能有俩main函数
-学基础阶段,可以在一个项目下有多个main函数,但是必须以file形式运行,不能以包形式运行
// 包导入,goland可以自动导入,(后期可以手动导入)
// go build 只编译(在什么平台下就编译成什么平台的可执行文件)----》交叉编译
// go run 编译并运行

5.1 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 // func 定义函数
// import 导入包
// package 声明包名
// var 定义变量的关键字 // 关键字不能作为变量的名字

5.2 37个保留字(对应内建的常量、类型和内置函数)

内建常量: 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
// 以后定义变量时,不能以数字开头,可以使用数字字母下划线组成的字符串来定义
// 变量的大小写,有特殊含义,区分大小写
// 变量定义推荐用驼峰体
-AgeOfPerson go语言和java语言推荐,python不推荐
-age_of_person 下划线方式,不推荐(go不推荐,python推荐)
// go文件的名字,建议使用下划线(参照源码)
-java语言中:变量和文件名都推荐用驼峰
-Python中:变量名和文件名都推荐用下划线

6 变量定义和使用

6 个点
-变量完整定义
-变量类型推导
-变量简略声明
-变量的使用,修改值,打印值
-同时定义多个变量
-变量要先定义,在使用,并且只能定义一次
// 变量的定义和使用

package main

import "fmt"

//var name = "lqz" // 作用域范围是全局,所有函数内部都可以使用

func main() {
// 方式一:完整定义 var关键字 变量名 类型 = 变量值
var NameOfCx string = "cx" // 定义不使用会报错、编译阶段报错
fmt.Println(NameOfCx) var age int = 19
fmt.Println(age) // 方式二:类型推导(不需要写类型) var关键字 变量名 = 变量值
var age2 = 19 // 没写类型、是推导出来的、也是固定不能改变
fmt.Println(age2) var NameOfCx2 = "cx"
fmt.Println(NameOfCx2) // 如何查看变量类型:Printf
fmt.Printf("变量的类型:%T,变量值:%s", NameOfCx2,NameOfCx2) // 方式三:简略声明 变量名 := 变量值
//age = 19 // 报错 变量没有定义
age3 := 19
fmt.Println(age3)
fmt.Printf("%T %d", age3, age3) // 变量的使用:修改值、打印值
var name string = "cx"
// 修改值 只能相同类型修改、在定义阶段就定义了类型、不能改类型
name = "wyz"
fmt.Println(name) //变量可以先定义再赋值
var age4 int // 只能使用方式一定义方式、不能推导
age4 = 100
fmt.Println(age4) // 一行同时定义多个变量:推导
var name5, age5, gender5 = "cx", 19, "男"
fmt.Println(name5, age5, gender5) // 一行同时定义多个变量:简略声明
name6, age6, gender6 := "cx", 19, "男"
fmt.Println(name6, age6, gender6) // 一行同时定义多个变量:var()
var (
name7 = "cx"
age7 = 19
gender7 = "男"
)
fmt.Println(name7, age7, gender7) // 变量要先定义 然后使用 并且只能定义一次
// 使用简略声明可以定义多次,但是实际是修改值
var age8 = 19
name8,age8 := "cx",20 // 有定义、有修改、修改的定义是修改
fmt.Println(age8, name8)
}

7 变量类型

// 基础数据类类型
-数字
-整型
-int
-int8
-int16
-int32
-int64
-正整数:无符号整型
-uint
-uint8
-uint16
-uint32
-uint64
-浮点型
-float32
-float64
-复数(正常开发中用不到)
-complex128
-complex64
-字符串
-string
-双引号或三引号包裹 (单引号不行:单引号表示数字)
-布尔
-bool
-true false (都是小写) -byte:uint8 的别名
-rune:int32 的别名 // 复合数据类型
-数组
-切片
-map
// 高级数据类型
-自定义的类型
-函数类型
-指针类型
// 基础的变量类型
package main func main() {
// 1 整型(表示正负整数 和 0) // var age int = 19
// int8 和其他区别在于,表示整数的范围不一样
// var age int8 = -128
// 一个int8 占8个比特位,8个小格只能放0或1,一个字节,所有它有2的8次方中变化,表示数字的大小2的7次方-1种变化
// 正负2的7次方-1 -128----+127
// int16 :正负2的15次方-1
// int32:正负2的31次方-1
// int64:正负2的63次方-1
// int :分平台,在32位机器,表示int32,在64位机器表示int64
// 以后,如果要定义一个变量,表示人的年龄
// var age int = 9223372036854775807
// fmt.Println(age) // 2 无符号整型 // var age uint =19
// fmt.Println(age) // uint8: 2的8次方-1 0---255之间
// var age uint8=255
// fmt.Println(age)
// uint16:2的16次方-1
// uint32:2的32次方-1
// uint64:2的63次方-1
// uint 在32位机器是 uint32,在64位机器是uint64 // 3 浮点型(小数),表示精度不一样
// var salary float32= 10.123456789 // 小数点后6位
// var salary2 float64= 10.123456789123456789 // 小数点后15位
// fmt.Println(salary)
// fmt.Println(salary2) // 4 复数 ---》有实部6 和 虚部 7
// var c complex64= 6 + 7i
// var d complex64= 2 + 3i
// fmt.Println(c+d)
// 结果:实部相加、虚部相加 // 5 字符串---》用双引号或反引号包裹---》反引号可以换行---->等同于python的三引号
// var name = "lqz \n" +"is \n" + "nb"
// var name2 = `彭于晏
// is
// very
// handsome`
// fmt.Println(name)
// fmt.Println(name2) // 6 单引号,表示的类型是什么? 数字类型,int32,这个字符对应的unicode编码的数字,所以单引号只能放一个字符
//var a ='A' // unicode编码你对应的数字
//var a int32='A' // unicode编码你对应的数字
//fmt.Println(a)
//fmt.Printf("a的类型是:%T",a) // a的类型是int32,它能够表示一个字符 // 7 布尔类型---->if判断中经常用到
//var b bool = true
//var b1 bool = false
//fmt.Println(b)
//fmt.Println(b1) // 8 byte:uint8 的别名 -rune:int32 的别名
//var a byte ='1' // 最大长度 1个字节,8个比特位,255种变化,只能表示ascii
//var b rune ='你' // 4个字节,表示一个字符,可以放所有的象形文字
//fmt.Println(a)
//fmt.Println(b)
} /*
Java与Go数字类型比较: java: byte short int long float double
go: int8 int16 int32 int64 float32 float64
python:int float 不是基础数据类型,是对象
*/

8 常量和iota

// 常量:不变的量、定义后就不变了
//
package main func main() {
// 常量定义格式:
// 1、const关键字 常量名 类型 = 值
// 2、const关键字 常量名 = 值
const name string="cx"
const age = 19 // 同时定义多个常量
const name2, age2 = "cx", 19
const (
name3 = "cx"
age3 = 18
)
const (
a4 = 1
b4 // 如果不赋值则遵从上面的赋值、相当于b4 = 1
c4
) // iota:是个自建常量 每换一行都会自增
const (
a5 = iota // 等同于 a5=0
b5
c5
)
const (
a6 = iota
b6 = 100
c6
d6
e6 = iota
) // 0 100 100 100 4 // 注意:
//同时定义多个常量,如果下一行只写常量名,遵从上一行的赋值方式
// iota每换一行,就会自增1,无论用还是不用
}

9 函数基础

// 函数基础

package main

import "fmt"

/*
注意:函数定义后可以不使用
1 定义函数基础语法:
func关键字 函数名(形参1 形参1类型,形参2 形参2类型)(返回值类型){
函数体内容(与缩进无关、括号内都是函数体内容)
}
*/ // 2 简单的函数定义、无参数无返回值
func test() {
fmt.Println("我是test")
} // 3 定义有参数、无返回值函数、参数类型相同
func test2(x int,y int) {
fmt.Println(x)
} // 4 定义有参数、无返回值、参数类型相同
func test3(a, b int, c,d string) {
fmt.Println(a,b,c,d)
} // 5 定义有2参数、有1个返回值 -- return
func test4(a,b int) int {
c := a+b
return c } // 6 定义2个参数、2个返回值
func test5(a, b int) (int,int) {
c := a+b
d := a*b
return c,d
} // 7 命名返回值,函数体不用重新定义
func test6(a, b int) (add int, mul int) {
add = a+b
mul = a*b
return // return可以直接省略add、mul
} func main() {
// 在main调用函数
fmt.Println("s5开始执行了")
test()
test2(10, 20) // 只有位置传参、没有关键字传参、没有默认参数(有几个参数就传几个)
test3(10,20,"cx","ll")
// 接收1个返回值
var a = test4(5,6)
b := test4(1,2)
fmt.Println(a,b)
// 接收两个返回值
a2,b2 := test5(6,6)
fmt.Println(a2,b2)
// 有多个返回值只接收1个、如果用变量接收但不实用、会报错
// _接收,不使用也不会报错
a3,_:=test5(4,5)
fmt.Println(a3) // 命名返回值的使用
add,mul := test6(1,2)
fmt.Println(add,mul)
}

10 函数高级

// 函数高级

package main

import "fmt"

// 注意:Go以包作为最小单位、所以函数名不能和同个包的函数重名
// 1 可变长参数
// 可接收任意长度int类型的参数
func test7(a ...int) {
fmt.Println(a) // 切片
} // 2 匿名函数:在main里 /*
3 函数也是一种类型--是一等公民/头等函数 go、python是 Java不是
指:可以把函数当变量使用 4 函数是变量 就可以当参数传递、当返回值返回 5 闭包函数:必须符合两个条件:
1、定义在函数内部
2、对外部作用域有引用
go有闭包函数、可以做出装饰器来 但是没有语法糖语法
*/ func test8() func() {
name := "cx"
a:=func(){
fmt.Println("内层函数")
fmt.Println(name)
}
return a } // 6 尽量要看懂:函数是变量 就可以当参数传递、当返回值返回
// 函数是一种类型、函数的参数和返回值都是类型的一部分
func test9(aa int) func(a int,b func())(int,func()){ return func(a int,b func())(int,func()) {
fmt.Println("我是内层函数")
return a, func() {}
}
} // 7 给类型重命名
type MyFunc func(a int,b func())(int,func()) func test10() MyFunc {
return func(a int,b func())(int,func()) {
fmt.Println("我是内层函数")
return a, func() {}
}
} func main() {
// 与python
test7(1,2,3,4,5) // 2 定义在函数内部的函数,必须是匿名函数
// 2.1 无参数
func (){
fmt.Println("我是匿名函数")
}() // 要执行否则报错
// 2.2 有参数
func (a,b int){
fmt.Println("我是匿名函数")
}(1,2)
// 2.3 有参数 有返回值
var a,b = func (a,b int)(int,int){
fmt.Println("我是匿名函数")
return a,b
}(1,2)
fmt.Println(a,b) // 3 函数是一等公民 --> 可以把函数赋值给一个变量
var f = func (){
fmt.Println("我是匿名函数")
}
fmt.Println(f) // 内存地址
f() // 调用
fmt.Printf("type:%T", f) // 4、5闭包
var f2 func()=test8()
f2() // 调用test9
// 方式一:
var f3 func(a int,b func())(int,func()) = test9(11)
f3(1,f2)
// 方式二:
var f4=test9(11)
f4(1,f2)
// 方式三:
f5:=test9(11) // 简略声明会方便很多、最常用
f5(1,f2)
}

1、Golang基础--Go简介、环境搭建、变量、常量与iota、函数与函数高级的相关教程结束。

《1、Golang基础--Go简介、环境搭建、变量、常量与iota、函数与函数高级.doc》

下载本文的Word格式文档,以方便收藏与打印。