Go学习笔记

1、字符串类型讲解

package main

import (
	"fmt"
	"strings"
)

func main() {
	var str1 = "你好"
	var str2 = "go"
	var str3 = fmt.Sprintf("%v%v", str1, str2) //+ 或者 fmt.Sprintf拼接字符串
	var str4 = str1 + str2
	fmt.Print(str3, "\n", str4, "\n")
	var str5 string = "123-456-789"
	a := strings.Split(str5, "-")
	fmt.Println(a)

	b := strings.Join(a, "*") //strings.Join 拼接
	fmt.Println(b)

	arr := []string{"php", "java", "python"}
	str6 := strings.Join(arr, "-")
	fmt.Println(str6)

	str7 := "this is str"
	str8 := "this"
	flag := strings.Contains(str7, str8) // strings.Contains 判断是否包含
	fmt.Println(flag)

	str9 := "this is str"
	str10 := "this"
	flag1 := strings.HasPrefix(str9, str10) // strings.HasPrefix 前缀判断是否存在
	flag2 := strings.HasSuffix(str9, str10) // strings.HasSuffix 后缀判断是否存在
	fmt.Println(flag1)
	fmt.Println(flag2)

	c := "this is sxxxxtr"
	d := "s"
	e := "w"
	sum := strings.Index(c, d)      // strings.Index 从前往后查找字符串出现的位置,查找不到返回-1,查找到返回下标
	sum1 := strings.LastIndex(c, d) // strings.LastIndex  从后往前查找字符串出现的位置
	sum2 := strings.Index(c, e)     // strings.Index  查找不到返回-1
	fmt.Println(sum, sum1, sum2)

	//注意:Sprintg 使用中需要注意格式转换,int 为%d  ; float 为%f ;bool 为%t ; byte 为%c
	var i int = 20
	var f float64 = 12.345
	var t bool = true
	var g byte = 'a'
	st1 := fmt.Sprintf("%d", i)
	fmt.Printf("值:%v 类型:%T \n", st1, st1)
	st2 := fmt.Sprintf("%f", f)
	fmt.Printf("值:%v 类型:%T \n", st2, st2)
	st3 := fmt.Sprintf("%t", t)
	fmt.Printf("值:%v 类型:%T \n", st3, st3)
	st4 := fmt.Sprintf("%c", g)
	fmt.Printf("值:%v 类型: %T \n", st4, st4)

}

2、流程控制 if分支

a、单分支

package main

import "fmt"

func main() {

	//实现功能:如果口罩的库存小于30个,提示库存不足
	var count int = 1
	//单分支
	if count < 30 {
		fmt.Println("01库存不足")
	}

	//if后面表达式,返回结果一定是true或者false
	//如果返回结果为true,那么{}中的代码会执行
	//如果返回结果为false,那么{}中的代码不会执行
	//if后面一定要有空格,和条件表达式分割开来
	//{}一定不能省略
	//条件表达式左右的()是建议省略的

	//在golang里,if后面考研并列的加入变量的定义:
	if count2 := 20; count2 < 30 {
		fmt.Println("02对不起,口罩存量不足")

	}

}

b、双分支

package main


import "fmt"


func main() {


    //实现功能:如果口罩库存小于30个,提示:库存不足,否则提示:库存充足
    //定义口罩的数量
    var count int = 1


    if count > 30 {
        fmt.Println("库存充足")
    } else {
        fmt.Println("库存不足")
    }


}

c、多分支

package main

import "fmt"

func main() {

	//实现功能:根据给出的学生分数,判断学生的等级
	// >=90	A
	// >=80 B
	// >=70 C
	// >=60 D
	// <60  E
	var score int = 98

	//多分支:优点,如果已经走了一个分支,那么下面的分支就不会判断执行
	if score >= 90 {
		fmt.Println("你的成绩是A级别")
	} else if score >= 80 { //else隐藏: score < 90
		fmt.Println("你的成绩是B级别")
	} else if score >= 70 {
		fmt.Println("你的成绩是C级别")
	} else if score >= 60 {
		fmt.Println("你的成绩是D级别")
	} else {
		fmt.Println("你的成绩是E级别")
	} //建议你保证else的存在,只有有了else才会真正 起到多选一的效果
}

3、switch

3.1switch分支1

package main

import "fmt"

func main() {
	//实现功能:根据给出的学生分数,判断学生的等级:
	//>=90	A
	//>=80	B
	//>=70	C
	//>=60	D
	//<60	E

	//给出一个学生分数
	var score int = 60
	//根据分数判断等级:
	//switch后面是一个表达式,这个表达式的结果依次跟case进行比较,满足结果执行后面代码
	//default是用来"兜底"的一个分支,其他的case分支都不走,就执行default分支
	//default分支可以放在任意位置上,不一定非要放在最后

	switch score / 10 {
	case 10:
		fmt.Println("您的等级为A")
	case 9:
		fmt.Println("您的等级为B")
	case 8:
		fmt.Println("您的等级为C")
	case 7:
		fmt.Println("您的等级为D")
	case 6:
		fmt.Println("您的等级为E")
	case 5:
		fmt.Println("您的等级为E")
	case 4:
		fmt.Println("您的等级为E")
	case 3:
		fmt.Println("您的等级为E")
	case 2:
		fmt.Println("您的等级为E")
	case 1:
		fmt.Println("您的等级为E")
	case 0:
		fmt.Println("您的等级为E")
	default:
		fmt.Println("您的成绩有误")
	}

}

3.2switch分支2

package main


import "fmt"


func main() {
    //1.switch后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
    switch 6 {
    case 10:
        fmt.Println("您的等级为A")
    case 9:
        fmt.Println("您的等级为B")
    default:
        fmt.Println("您的成绩有误")
    }
    //2.case后面的表达式如果是常量值(字面量),则要求不能重复
    //3.case后的各个值的数据库类型,必须和switch的表达式数据类型一致
    //4.case后面可以带多个值,使用逗号间隔.如 case 1,2....
    var a int = 7
    switch a {
    case 10:
        fmt.Println("您的等级为A")
    case 7, 8, 9:
        fmt.Println("您的等级为B")
    default:
        fmt.Println("您的成绩有误")
    }
    //5.case后面不需要带break
    //6.default语句不是必须的,位置也是随意的
    //7.switch后也可以不带表达式,当做if分支来使用
    var b int = 1
    switch {
    case b == 1:
        fmt.Println("11111")
    case b == 2:
        fmt.Println("22222")


    }
    //8.switch后也可以直接声明/定义一个变量,分号结束,不推荐
    switch b := 6; {
    case b > 6:
        fmt.Println("大于6")
    case b <= 6:
        fmt.Println("不大于6")


    }
    //9.switch穿透,利用fallthrough关键字,如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透
    var c int = 10
    switch c {
    case 10:
        fmt.Println("您的等级为A")
        fallthrough
    case 7, 8, 9:
        fmt.Println("您的等级为B")
    default:
        fmt.Println("您的成绩有误")
    }
}

4、for循环

package main

import "fmt"

func main() {

	//实现一个功能:求和1+2+3+4+5
	//for 循环解决

	//for循环的语法格式:
	//for 初始表达式;布尔表达式(条件判断);迭代因子 {循环体;--反复重复执行的内容 }
	var sun int = 0
	for i := 1; i <= 5; i++ {
		sun += i
	}

	//输出结果:
	fmt.Println(sun)
	//注意:for循环实际就是让程序员写代码效率提高,但是底层该怎么执行还是怎么执行,底层效率没提高
}

5、切片

package main

import "fmt"

func main() {
    //关于切片的长度和容量
    //长度:切片的长度就是它包含元素的个数
    //容量:切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数
    arr := []int{11, 22, 33, 44}
    a := arr[:]
    b := arr[1:2]
    fmt.Println(a)
    fmt.Println(b)

    fmt.Printf("切片的长度%v  切片的容量%v \n", len(a), cap(a))
    fmt.Printf("切片的长度%v  切片的容量%v", len(b), cap(b))

}

Go学习笔记_第1张图片

6、函数

package main

import "fmt"

/* func main() {
	//求2数之和
	var a int = 10
	var b int = 30
	var sun int = 0
	sun = a + b
	fmt.Println(sun)

	var a1 int = 11
	var b1 int = 30
	var sun1 int = 0
	sun1 = a1 + b1
	fmt.Println(sun1)
} */

func cal(i1 int, i2 int) int { //i1,i2是  形参
	var sum2 int = 0
	sum2 = i1 + i2
	return sum2
}

func main() {
	sum2 := cal(11, 23) // 11和23  是实参
	fmt.Println(sum2)
}

/*
1.为什么要使用函数:提高代码的复用型,减少代码的冗余,代码的维护性也提高了
2.函数的定义:为完成某一功能的程序指令(语句)的集合,称为函数
3.基本的语法

func 函数名 (形参列表) (返回值类型列表) {
	执行语句..
	return + 返回值类型

*/

函数详细讲解01- _ 下划线忽略返回值

package main

import "fmt"

//计算2个数的和,2个数的差
func cal(i1 int, i2 int) (int, int) {
	var sum int = 0
	var result int = 0
	sum = i1 + i2
	result = i1 - i2
	return sum, result
}

func main() {

	/* 	sum, result := cal(31, 21)
	   	fmt.Println(sum, result) */

	_, result := cal(30, 20) //如果不想换回另外一个形参,可以用 _ 忽略返回值
	fmt.Println(result)

	sum, _ := cal(30, 20) //如果不想换回另外一个形参,可以用 _ 忽悠返回值
	fmt.Println(sum)
}

函数详情讲解02-内存分析

package main

import "fmt"

//自定义函数: 功能:交换2个数


func exchangeNum(num1 int, num2 int) {
	var t int
	t = num1
	num1 = num2
	num2 = t
}

func main() {
	var num1 int = 10
	var num2 int = 20
	fmt.Println("交换前的2个数: num1 = %v, num2 = %v \n", num1, num2)

	exchangeNum(num1, num2)
	fmt.Println("交换后的2个数: num1 = %v, num2 = %v \n", num1, num2)
}

Go学习笔记_第2张图片

函数详情讲解03

package main

import "fmt"

//函数的参数为:可变参数 ...    参数的数量可变
//args...int 可以传入任意多个数量的int类型的数据,传入0个,1个,。。。N个
func test(args ...int) {
	//函数内部处理可变参数的时候,将可变参数当做切片来处理
	//遍历可变参数
	for i := 0; i < len(args); i++ {
		fmt.Println(args[i])
	}
}

func main() {
	test()
	fmt.Println("----")
	test(1, 12)
	fmt.Println("----")
	test(11, 22, 333, 4444, 56789)
}

基本数据类型和数组默认都是传递的,即进行值的拷贝,在函数内修改,不会影响到原来的值

package main

import "fmt"

func cal(args int) {
	//基本数据类型和数组默认都是传递的,即进行值的拷贝,在函数内修改,不会影响到原来的值
	args = 30
	fmt.Println("cal", args)
}

func main() {
	var args int = 10
	cal(args)
	fmt.Println("main", args)
}

在Go中,函数也是一种数据类型,可以赋值给变量,则该变量就是一个函数类型的变量了,通过该变量可以对函数调用

package main

import "fmt"

func test(a int) {
	fmt.Println(a)
}

func main() {
	//函数也是一种数据类型,可以赋值给一个变量
	b := test //变量就是一个函数类型的变量
	fmt.Printf("a的类型是: %T,test的函数类型是: %T \n", b, test)

	//通过该变量可以对函数调用
	b(10)
}

7、指针

package main

import "fmt"

func main() {
	//在计算机底层a这个变量其实对应了一个内存地址
	//指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的地址
	a := 10
	b := &a //b是指针变量  b的类型  *int(指针类型)

	fmt.Printf("a的值:%v  a的类型%T   a的地址%p\n", a, a, &a)
	fmt.Printf("b的值:%v  b的类型%T   b的地址%p\n", b, b, &b)

	fmt.Println(b)  //a的地址  0xc0000a0058
	fmt.Println(*b) //*b 表示打印a对应的值 10

	*b = 30 //改变b这个变量对应的内存地址的值
	fmt.Println(a)
}

Go学习笔记_第3张图片

8、结构体

package main

import "fmt"

type Person struct {
	name string
	age  int
	sex  string
}

func main() {
	var p1 Person
	p1.age = 18
	p1.name = "李四"
	p1.sex = "男"
	fmt.Printf("值%#v   类型%T\n", p1, p1)

	var p2 = new(Person)
	p2.age = 18
	p2.name = "雅典娜"
	p2.sex = "女"
	fmt.Printf("值%#v   类型%T \n", p2, p2)

	var p3 = new(Person)
	p3.age = 20
	p3.name = "斯巴达"
	p3.sex = "男"
	fmt.Printf("值%#v   类型%T\n", p3, p3)

	var p4 = Person{
		name: "张三",
		age:  18,
		sex:  "男",
	}
	fmt.Printf("值%#v   类型%T\n", p4, p4)

}

9、协程,并行

package main

import (
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func test() {
	for i := 0; i < 10; i++ {
		fmt.Println("test() 你好golang", i)
		time.Sleep(time.Millisecond * 100)
	}
	wg.Done() //协程计数器加-1
}

func main() {
	wg.Add(1) //协程计数器加+1
	go test()
	for i := 0; i < 10; i++ {
		fmt.Println("main() 你好golang", i)
		time.Sleep(time.Millisecond * 50)
	}
	wg.Wait() //等待协程执行完毕
	fmt.Println("main 主进程退出")
}

10、文件读取和写入

package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
)

// 读取数据
// 读取数据
func readFile(str string) {
	fileStr, err := ioutil.ReadFile(str)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(fileStr))
}




func ioutilWriteFile(str string) {
	//写入数据
	err := ioutil.WriteFile("E:/test.txt", []byte(str), 0666)
	if err != nil {
		fmt.Println(err)
		return
	}
}

func osDddWriteFile(str string) {
	//os.O_CREATE创建 	os.O_WRONLY写入 os.O_APPEND追加
	file, err := os.OpenFile("E:/test1.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	defer file.Close() //关闭文件

	if err != nil {
		fmt.Println(err)
		return
	}
	file.WriteString(str)
}

func osTRUNCWriteFile(str string) {
	//os.O_CREATE创建 	os.O_WRONLY写入 os.O_TRUNC清空
	file, err := os.OpenFile("E:/test2.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	defer file.Close() //关闭文件

	if err != nil {
		fmt.Println(err)
		return
	}
	file.WriteString(str)
}

func bufioWriteFile(str string) {
	//os.O_TRUNC清空写入数据
	file, err := os.OpenFile("E:/test3.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	defer file.Close() //关闭文件

	if err != nil {
		fmt.Println(err)
		return
	}
	writer := bufio.NewWriter(file)
	writer.WriteString(str) //将数据写入缓存
	writer.Flush()          //将缓存中的内容写入文件
}

func main() {

	readFile("E:/a.txt")


	ioutilWriteFile("nihao 123")

	//循环插入多条数据
	for i := 0; i < 10; i++ {
		//strconv.Itoa(i) 转发成string    "\r\n"换行
		osDddWriteFile("1111" + strconv.Itoa(i) + "\r\n")
	}

	osTRUNCWriteFile("222222" + "\r\n")

	bufioWriteFile("nihao go")
}

11.连接mysql

package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
	Id      int
	Keyword string `gorm:"column:keywords"`
	City    string
}

func (User) TableName() string {
	return "user"
}

func read(client *gorm.DB, Id int) *User {
	var users []User

	client.Where("Id=?", Id).Find(&users)

	if len(users) > 0 {
		return &users[0]
	} else {
		return nil
	}

}

func main() {
	dataSourceName := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True"

	client, err := gorm.Open(mysql.Open(dataSourceName), nil)
	if err != nil {
		fmt.Printf("错误%v", err)
	}

	user := read(client, 1) //读取数据
	if user != nil {
		fmt.Printf("%#v \n", *user)
	} else {
		fmt.Println("无结果")
	}

	client.Model(User{}).Where("id=?", 2).Delete(User{}) //删除数据

	user1 := User{
		Id:      2,
		Keyword: "golang",
		City:    "武汉",
	}
	client.Create(user1) //插入数据

	client.Model(User{}).Where("id=?", 2).Update("Keyword", "GO") //修改数据

}

12.连接redis

package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/redis/go-redis"
)

func string(ctx context.Context, client *redis.Client) {
	key := "name"
	value := "大脸猫"

	err := client.Set(ctx, key, value, 1*time.Second).Err()
	checkError(err)

	client.Expire(ctx, key, 3*time.Second)
	time.Sleep(2 * time.Second)
	v2, err := client.Get(ctx, key).Result()
	checkError(err)
	fmt.Println(v2)

	client.Del(ctx, key)
}

func main() {

	client := redis.NewClient(&redis.Options{
		Addr:     "1270.0.01:6379",
		Password: "dafasf@131.",
		DB:       0,
	})
	ctx := context.TODO()

	string(ctx, client)
}

func checkError(err error) {
	if err != nil {
		if err == redis.Nil {
			fmt.Println("key不存在")
		} else {
			fmt.Println(err)
			os.Exit(1)
		}

	}
}

你可能感兴趣的:(go,golang,学习,笔记)