goland学习笔记(一)

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)
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿槿吃糖

只要出现在这里,我就能看到你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值