pdf课件:《8小时转职Golang工程师-语法部分》.pdf
01 hello world
代码块
package main //程序的包名
import "fmt"
//main函数
func main() {
fmt.Print(" hello world ")
}
导包方式
单一模块导入
import "fmt"
多模块导入
import (
"fmt"
"time"
)
举例:
package main //程序的包名
import (
"time"
"fmt"
)
//main函数
func main() {
fmt.Println(" hello world ")
time.Sleep(1 * time.Second)
}
02 四种变量的声明方式
以下执行在 func main(){xxxx } 函数体内。
思维导图
单一变量声明
⚠️注意:方法四只能用来在局部变量定义(函数体内的定义),不能用在全局变量
//方法一:声明一个变量 默认的值是0
var a int
fmt.Println("a = ", a)
fmt.Printf("type of a = %T\n", a)
//方法二:声明一个变量,初始化一个值
var b int = 100
fmt.Println("b = ", b)
fmt.Printf("type of b = %T\n", b)
var bb string = "abcd"
fmt.Printf("bb = %s, type of bb = %T\n", bb, bb)
//方法三:在初始化的时候,可以省去数据类型,通过值自动匹配当前的变量的数据类型
var c = 100
fmt.Println("c = ", c)
fmt.Printf("type of c = %T\n", c)
var cc = "abcd"
fmt.Printf("cc = %s, type of cc = %T\n", cc, cc)
//方法四:(常用的方法)省去var关键字,直接自动匹配
e := 100
fmt.Println("e = ", e)
fmt.Printf("type of e = %T\n", e)
f := "abcd"
fmt.Println("f = ", f)
fmt.Printf("type of f = %T\n", f)
g:=3.14
fmt.Println("g = ", g)
fmt.Printf("type of g = %T\n", g)
多变量声明
// 声明多个变量
var xx, yy int = 100, 200
fmt.Println("xx = ", xx, ", yy = ", yy)
var kk, ll = 100, "Aceld"
fmt.Println("kk = ", kk, ", ll = ", ll)
//多行的多变量声明
var (
vv int = 100
jj bool = true
)
fmt.Println("vv = ", vv, ", jj = ", jj)
03 常量和iota
⚠️注意:iota 只能够配合const() 一起使用, iota只有在const进行累加效果。
//const 来定义枚举类型
const (
//可以在const() 添加一个关键字 iota, 每行的iota都会累加1, 第一行的iota的默认值是0
BEIJING = 10*iota //iota = 0
SHANGHAI //iota = 1
SHENZHEN //iota = 2
)
const (
a, b = iota+1, iota+2 // iota = 0, a = iota + 1, b = iota + 2, a = 1, b = 2
c, d // iota = 1, c = iota + 1, d = iota + 2, c = 2, d = 3
e, f // iota = 2, e = iota + 1, f = iota + 2, e = 3, f = 4
g, h = iota * 2, iota *3 // iota = 3, g = iota * 2, h = iota * 3, g = 6, h = 9
i, k // iota = 4, i = iota * 2, k = iota * 3 , i = 8, k = 12
)
func main() {
//常量(只读属性)
const length int = 10
fmt.Println("length = ", length)
//length = 100 //常量是不允许修改的。
fmt.Println("BEIJIGN = ", BEIJING)
fmt.Println("SHANGHAI = ", SHANGHAI)
fmt.Println("SHENZHEN = ", SHENZHEN)
fmt.Println("a = ", a, "b = ", b)
fmt.Println("c = ", c, "d = ", d)
fmt.Println("e = ", e, "f = ", f)
fmt.Println("g = ", g, "h = ", h)
fmt.Println("i = ", i, "k = ", k)
// iota 只能够配合const() 一起使用, iota只有在const进行累加效果。
//var a int = iota
}
❌错误方式
func main() {
// iota 只能够配合const() 一起使用, iota只有在const进行累加效果。
var a int = iota
}
04 return 返回值
单个返回值
func foo1(a string, b int) int {
fmt.Println("a = ", a)
fmt.Println("b = ", b)
c := 100
return c
}
func main() {
c := foo1("abc", 555)
fmt.Println("c = ", c)
}
多个返回值
func foo1(a string, b int) int {
fmt.Println("a = ", a)
fmt.Println("b = ", b)
c := 100
return c
}
//返回多个返回值,匿名的
func foo2(a string, b int) (int, int) {
fmt.Println("a = ", a)
fmt.Println("b = ", b)
return 666, 777
}
//返回多个返回值,有形参名称的
func foo3(a string, b int) (r1 int, r2 int) {
fmt.Println("----- foo3 -----")
fmt.Println("a = ", a)
fmt.Println("b = ", b)
//r1 r2 属于foo3的形参,初始化默认的值是0
//r1 r2 作用域空间 是foo3 整个函数体的{}空间
fmt.Println("r1 = ", r1)
fmt.Println("r2 = ", r2)
//给有名称的返回值变量赋值
r1 = 1000
r2 = 2000
return
}
func foo4(a string, b int) (r1, r2 int) {
fmt.Println("---- foo4 ----")
fmt.Println("a = ", a)
fmt.Println("b = ", b)
r1 = 1000
r2 = 2000
return
}
func main() {
c := foo1("abc", 555)
fmt.Println("c = ", c)
ret1, ret2 := foo2("haha", 999)
fmt.Println("ret1 = ", ret1, " ret2 = ", ret2)
re1, re2 := foo3("foo3", 333)
fmt.Println("ret1 = ", re1, " ret2 = ", re2)
r1, r2 := foo4("foo4", 333)
fmt.Println("ret1 = ", r1, " ret2 = ", r2)
}
05 init
⚠️注意:函数名开头为大写的时候,可以对外开放,否则只能在当前脚本页使用。
_匿名导入,import后可以不调用,可执行init
06 指针
07 defer
defer的执行顺序
defer 的执行顺序,是压栈的方式。(类似弹夹)
package main
import "fmt"
func func1(){
fmt.Println("A")
}
func func2() {
fmt.Println("B")
}
func func3() {
fmt.Println("C")
}
func main() {
defer func1()
defer func2()
defer func3()
}
执行结果
return和defer哪个先执行
08 切片slice
动态数组
package main
import (
"fmt"
)
func printArray(myArray [4]int) {
//值拷贝
for index, value := range myArray {
fmt.Println("index = ", index, ", value = ", value)
}
}
func printArray2(myArray []int) {
//引用传递
// _ 表示匿名的变量
for _, value := range myArray {
fmt.Println("value = ", value)
}
myArray[0] = 100
}
func main() {
//固定长度的数组
var myArray1 [10]int
myArray2 := [10]int{1, 2, 3, 4}
myArray3 := [4]int{11, 22, 33, 44}
for i := 0; i < len(myArray1); i++ {
fmt.Println(myArray1[i])
}
for index, value := range myArray2 {
fmt.Println("index = ", index, ", value = ", value)
}
//查看数组的数据类型
fmt.Printf("myArray1 types = %T\n", myArray1)
fmt.Printf("myArray2 types = %T\n", myArray2)
fmt.Printf("myArray3 types = %T\n", myArray3)
printArray(myArray3)
ajinArray := []int{1, 2, 3, 4} //动态数组,切片slice
fmt.Printf("ajinArray type is %T\n", ajinArray)
printArray2(ajinArray)
fmt.Println(" ==== ")
for _, value := range ajinArray {
fmt.Println("value = ", value)
}
}
声明方式
func main() {
//声明slice1是一个切片,但是并没有给slice分配空间
var slice1 []int
//通过make开辟空间,默认值为0
slice1 = make([]int, 3)
slice1[0] = 100
fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)
}
func main() {
//声明slice1是一个切片,同时给slice分配空间,3个空间,初始化值是0
var slice1 []int = make([]int, 3)
slice1[0] = 100
fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)
}
func main() {
//声明slice1是一个切片,同时给slice分配空间,3个空间,初始化值是0,通过:=推导出slice是一个切片
slice1 := make([]int, 3)
slice1[0] = 100
fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)
}
func main() {
//声明slice1是一个切片,但是并没有给slice分配空间
var slice1 []int
fmt.Printf("len = %d, slice = %v\n", len(slice1), slice1)
//判断一个slice是否为0
if slice1 == nil {
fmt.Println("slice1 是一个空切片")
} else {
fmt.Println("slice 是有空间的 ")
}
}
容量、自动扩容
func main() {
var numbers = make([]int,3,5)
// cap是容量
fmt.Printf("len = %d, cap = %d, slice = %v\n",len(numbers),cap(numbers),numbers)
numbers = append(numbers,1)
fmt.Printf("len = %d, cap = %d, slice = %v\n",len(numbers),cap(numbers),numbers)
numbers = append(numbers,2)
fmt.Printf("len = %d, cap = %d, slice = %v\n",len(numbers),cap(numbers),numbers)
numbers = append(numbers,3)
fmt.Printf("len = %d, cap = %d, slice = %v\n",len(numbers),cap(numbers),numbers)
numbers = append(numbers,4)
fmt.Printf("len = %d, cap = %d, slice = %v\n",len(numbers),cap(numbers),numbers)
}
截取
func main() {
s := []int{1,2,3}//len = 3, cap = 3, [1,2,3]
//[0,2]
s1 := s[0:2] //[1,2] 同python,左闭右包
//copy 可以将底层数组的slice一起进行拷贝 ,值拷贝
s2 := make([]int,3)
//将s中的值 依次拷贝到s2中
copy(s2,s)
s1[0] = 100
fmt.Println(s)
fmt.Println(s1)
fmt.Println(s2)
}
09 map
声明方式
func main() {
//声明myMap1 是一种map类型 key是string,value是string
var myMap1 map[string]string
if myMap1 == nil {
fmt.Println("myMap1 是一个空map")
}
//无序
myMap1 = make(map[string]string, 10)
myMap1["one"] = "java"
myMap1["two"] = "c++"
myMap1["three"] = "python"
fmt.Println(myMap1)
//第二种声明方式
myMap2 := make(map[int]string)
myMap2[1] = "java"
myMap2[2] = "php"
myMap2[3] = "python"
fmt.Println(myMap2)
//第三种声明方式
myMap3 := map[string] string{
"one":"php",
"two":"c++",
"three":"python",
}
fmt.Println(myMap3)
}
使用方式
func printMap(cityMap map[string]string){
//cityMap 是一个引用传递
for key, value := range cityMap{
fmt.Println("key = ", key)
fmt.Println("value = ",value)
}
}
func changeValue(cityMap map[string]string){
cityMap["england"] = "london"
}
func main() {
cityMap := make(map[string]string)
//添加
cityMap["china"] = "beijing"
cityMap["japan"] = "tokyo"
cityMap["usa"] = "newyork"
//遍历
for key, value := range cityMap{
fmt.Println("key = ", key)
fmt.Println("value = ",value)
}
//删除
delete(cityMap, "china")
//修改
cityMap["usa"] = "dc"
fmt.Println("---------")
changeValue(cityMap)
//遍历
printMap(cityMap)
}
10 结构体struct
基本定义
import "fmt"
//声明一种行的数据类型 myint,是int的一个别名
type myint int
//定义一个结构体
type Book struct {
title string
auth string
}
func changeBook(book Book) {
//传递一个book的副本
book.auth = "666"
}
func changBook2(book *Book) {
//指针传递
book.auth = "777"
}
func main() {
var book1 Book
book1.title = "goland"
book1.auth = "zhang3"
fmt.Printf("%v\n", book1)
changeBook(book1)
fmt.Printf("%v\n", book1)
changBook2(&book1)
fmt.Printf("%v\n", book1)
}
面向对象
type Hero struct {
Name string
Ad int
Level int
}
func (this Hero) Show() {
fmt.Println("Name = ", this.Name)
fmt.Println("Ad = ", this.Ad)
fmt.Println("Level = ", this.Level)
}
func (this Hero) GetName() string{
return this.Name
}
func (this Hero) SetName(newName string) {
//this 是调用该方法的对象的一个副本(拷贝)
this.Name = newName
}
func main() {
// 创建一个对象
hero := Hero{Name: "zhang3", Ad: 100, Level:1}
hero.Show()
hero.SetName("li4")
hero.Show()
}
- 需要传指针,结构体的属性值才能被修改
- 通过大小写区别是否可以被其他包调用
//如果类名首字母大写,表示其他包也能够访问
type Hero struct {
//如果说类的属性首字母大写,表示该属性是对外能够访问的,否则的话只能够类的内部访问
Name string
Ad int
Level int
}
继承
type Human struct {
name string
sex string
}
func (this *Human) Eat() {
fmt.Println("Human.Eat()...")
}
func (this *Human) Walk() {
fmt.Println("Human.Walk()...")
}
type SuperMan struct {
Human // SuperMan类继承了Human类的方法
level int
}
//重定义父类的方法
func (this *SuperMan) Eat() {
fmt.Println("SuperMan.Eat()...")
}
//子类的新方法
func (this *SuperMan) Fly() {
fmt.Println("SuperMan.Fly()...")
}
func (this *SuperMan) Print() {
fmt.Println("name = ",this.name)
fmt.Println("sex = ",this.sex)
fmt.Println("level = ",this.level)
}
func main() {
h := Human{"zhang3", "female"}
h.Eat()
h.Walk()
//定义一个子类对象
//s := SuperMan{Human{"li4","female"},88}
var s SuperMan
s.name = "li4"
s.sex = "male"
s.level = 88
s.Walk() //父类的方法
s.Eat() //父类的方法
s.Fly() //父类的方法
s.Print()
}
多态
基本要素
type AnimalIF interface {
Sleep()
GetColor() string
GetType() string
}
//具体的类
type Cat struct {
color string //猫的颜色
}
func (this *Cat) Sleep() {
fmt.Println("Cat is Sleep")
}
func (this *Cat) GetColor() string {
return this.color
}
func (this *Cat) GetType() string {
return "Cat"
}
//具体的类
type Dog struct {
color string
}
func (this *Dog) Sleep() {
fmt.Println("Dog is Sleep")
}
func (this *Dog) GetColor() string {
return this.color
}
func (this *Dog) GetType() string {
return "Dog"
}
func showAnimal(animal AnimalIF) {
animal.Sleep() //多态
fmt.Println("color = ", animal.GetColor())
fmt.Println("kind = ", animal.GetType())
}
func main() {
var animal AnimalIF //接口的数据类型,父类指针
animal = &Cat{"Green"}
animal.Sleep() //调用的就是Cat的Sleep()方法,多态的现象
animal = &Dog{"Yellow"}
animal.Sleep() //调用的就是Dog的Sleep()方法
cat := Cat{"Green"}
dog := Dog{"Yellow"}
showAnimal(&cat)
showAnimal(&dog)
}
interface
//interface{}是万能数据类型
func myFunc(arg interface{}) {
fmt.Println("myFunc is called...")
fmt.Println(arg)
//interface{} 改如何区分 此时引用的底层数据类型到底是什么?
//给 interface{} 提供 “类型断言” 的机制
value, ok := arg.(string)
if !ok {
fmt.Println("arg is not string type")
} else {
fmt.Println("arg is string type, value = ", value)
fmt.Printf("value type is %T\n", value)
}
}
type Book struct {
auth string
}
func main() {
book := Book{"Golang"}
myFunc(book)
myFunc(100)
myFunc("abc")
myFunc(3.14)
}