😋 大家好,我是YAy_17,是一枚爱好网安的小白。
本人水平有限,欢迎各位大佬指点,欢迎关注 😁,一起学习 💗 ,一起进步 ⭐ 。
⭐ 此后如竟没有炬火,我便是唯一的光。 ⭐
Go语言学习Day1
package main
//表示hello.go文件所在的包是main,在GO中每一个文件都归属于一个包
import "fmt"
//导入一个包,“fmt”,之后便可以使用fmt中的函数,例如"fmt.Println()"
func main() {
//func是一个关键字,main是函数名,同时也是主函数,是整个程序的入口
fmt.Println("hello world")
//使用fmt包中的函数Println()来输出hello world
}
GO语言的两种执行流程
先编译(go build *.go文件)生成可执行文件(*.exe),之后再运行可执行文件;(可以生成自己命名的可执行程序,go build -o myhello.exe hello.go)
直接使用go run *.go文件,进行运行
两种执行流程的区别和优缺点:
如果我们先编译生成可执行文件,再运行可执行文件,那么我们可以将生成的可执行文件移植到一台没有go开发环境的机器上进行执行
如果我们是直接使用 go run *.go文件,那么就需要运行的机器必须具备go语言的开发环境
在编译的时候,编译器会将程序运行所依赖的库文件全部包含到可执行文件中,因此生成的可执行文件比较大
Go语言的开发注意事项
Go语言常用的转义字符
// Go语言中的常用转移字符
package main
import "fmt"
func main() {
fmt.Println("hello\nworld!")
fmt.Println("hello\tY4y17")
fmt.Println("D:\\Microsoft VS Code\\GO\\Gocode\\src\\go_code")
fmt.Println("Y4y17说\"Golang yyds\"")
fmt.Println("小黑子露出鸡脚了吧\r我是ikun")
}
需要注意的是最后面的\r,其他的都比较的熟悉,\r代表着:输出当前行的内容,然后从\r后面开始的地方,覆盖掉最前面的内容
标识符、关键字和命名规则
标识符的组成
标识符只能由数字、字母和下划线组成
标识符的开头只能是字母和下划线
标识符是区分大小写的
package main
import "fmt"
func main(){
var name string //定义变量的时候要写上var 然后是变量的名字 最后是变量的类型
var age int
var _sys int
}
关键字
GO语言提供了25个关键字;
Golang变量声明
声明变量的语法:
var idetifier type
var:声明变量的关键字
identifier:变量的名称
type:变量的类型
PS:定义变量之后,必须要使用,不使用就会出错!
批量声明
package main
var(
name string
age int
b bool
)
尝试打印输出:
变量初始化
逐个变量进行初始化
func main() {
var name string = "Y4y17"
var age int = 21
var b bool = true
fmt.Printf("name:%v\n", name)
fmt.Printf("age:%v\n", age)
fmt.Printf("b:%v", b)
}
多个变量初始化
func main() {
var name,age,b = "Y4y17",21,true
fmt.Printf("name:%v\n", name)
fmt.Printf("age:%v\n", age)
fmt.Printf("b:%v", b)
}
类型推断
var name = "Y4y17" //不需要后面的数据类型
短变量声明
在函数内部,可以使用:=运算符对变量进行声明和初始化
package main
func main(){
name := "Y4y17"
age := 21
}
这种方法只适合在函数内部,函数外部不能使用
匿名变量
package main
import "fmt"
func GetNameAndAge() (string, int) {
return "Y4y17", 21
}
func main() {
name, age := GetNameAndAge()
fmt.Printf("name:%v\tage:%v", name, age)
}package main
import "fmt"
func GetNameAndAge() (string, int) {
return "Y4y17", 21
}
func main() {
name, age := GetNameAndAge()
fmt.Printf("name:%v\tage:%v", name, age)
}
//有的时候比如name没有用到,我们还可以用下划线替换掉name
func GetNameAndAge() (string, int) {
return "Y4y17", 21
}
func main() {
_,age := GetNameAndAge()
fmt.Printf("age:%v",age)
}
常量的初始化
有一个比较特殊的常量,他是可以更改值的,iota默认开始值为0,每调用一次加1,遇到const关键字的时候被重置为0
package main
import (
"fmt"
)
func main() {
const (
a1 = iota
a2 = iota
a3 = iota
)
fmt.Printf("a1: %v\n", a1)
fmt.Printf("a2: %v\n", a2)
fmt.Printf("a3: %v\n", a3)
}
//输出的结果为0 1 2
使用”_“来跳过某一些值
package main
import (
"fmt"
)
func main() {
const (
a1 = iota
_
a3 = iota
)
fmt.Printf("a1: %v\n", a1)
fmt.Printf("a3: %v\n", a3)
}
//输出的结果为0 2
iota中间插队
package main
import (
"fmt"
)
func main() {
const (
a1 = iota
_
a3 = iota
)
fmt.Printf("a1: %v\n", a1)
fmt.Printf("a3: %v\n", a3)
}
//输出的结果为0 2
Go语言的数据类型
package main
import (
"fmt"
)
func main() {
var name string = "zhangsan"
age := 20
b := true
fmt.Printf("%T\n%T\n%T\n", name, age, b)
inter := &age
fmt.Printf("%T\n", inter)
a := [2]int{1, 2}e
fmt.Printf("%T\n", a)
c := []int{1,2,3}
fmt.Printf("%T\n",c)
}
分别输出:
最后面的c := []int{1,2,3} 他不是数组,它叫做切片,也是个动态的数组,就是当长度不指定的时候,便是切片;
数字类型:
Go语言字符串字面量
在Go语言中,字符串字面量使用双引号”“或者是反引号来创建。在Go语言中没有char类型,单行的字符串用双引号,多行的字符串用的是反引号;
package main
import "fmt"
func main() {
var str string = "hello"
str2 := `
line 1
line 2
line 3
`
fmt.Printf("str: %v\n", str)
fmt.Printf("str2: %v\n", str2)
}
字符串的连接
”+“号
package main
import (
"fmt"
)
func main() {
name := "Y4y17"
age := "20"
s := name + age
fmt.Printf("s: %v\n", s)
}
fmt.Sprintf()
package main
import (
"fmt"
)
func main() {
name := "Y4y17"
age := "20"
s1 := fmt.Sprintf("%v,%v", name, age)
fmt.Printf("s1: %v\n", s1)
}
strings.Join()
package main
import (
"fmt"
"strings"
)
func main() {
name := "Y4y17"
age := "20"
s2 := strings.Join([]string{name, age}, ",")
fmt.Printf("s2: %v\n", s2)
}
//strings.Join这种方式,两个参数,第一个参数是一个用来连接的空的数组,第二个参数是
//用来连接时的中间的分隔符
write.buffer
package main
import (
"bytes"
"fmt"
)
func main() {
var buffer bytes.Buffer
buffer.WriteString("Y4y17")
buffer.WriteString(",")
buffer.WriteString("20")
fmt.Printf("buffer.String(): %v\n", buffer.String())
}
Go语言中的切片操作
package main
import "fmt"
func main() {
s := "hello world"
n := 3
m := 5
fmt.Printf("s[n]: %v\n", s[n])
fmt.Printf("s[n:m]: %v\n", s[n:m]) //前闭后开区间 [)
fmt.Printf("s[n:]: %v\n", s[n:])
fmt.Printf("s[:m]: %v\n", s[:m])
}
Go语言中的字符串函数
package main
import (
"fmt"
"strings"
)
func main() {
s := "hello World"
//返回字符串的长度
fmt.Printf("len(s): %v\n", len(s))
//字符串的分割函数
fmt.Printf("strings.Split(s, \" \"): %v\n", strings.Split(s, " "))
//判断字符串中是否包含另一个字符串
fmt.Printf("strings.Contains(s, \"hello\"): %v\n", strings.Contains(s, "hello"))
//转换小写
fmt.Printf("strings.ToLower(s): %v\n", strings.ToLower(s))
//转化大写
fmt.Printf("strings.ToUpper(s): %v\n", strings.ToUpper(s))
//判断字符串中是否含有某个前缀
fmt.Println(strings.CutPrefix(s, "hello"))
//判断字符串中时候含有某个后缀
fmt.Println(strings.CutSuffix(s, "World"))
}
Go格式化输出
package main
import "fmt"
type website struct {
name string
}
func main() {
site := website{name: "Y4y17.com"}
fmt.Printf("site: %v\n", site) //%v 代表的就是var
fmt.Printf("site: %#v\n", site) //%#v 会将详细内容输出
fmt.Printf("site: %T\n", site) //%T代表的是type
}
Go语言的运算符
与其他的语言一样,+ - * / %的用法都是一样的,当然还有自增和自减的运算符(++ --)
package main
import "fmt"
func main() {
a := 10
b := 21
fmt.Printf("a: %v\n", a)
fmt.Printf("b: %v\n", b)
fmt.Printf("(a + b): %v\n", (a + b))
fmt.Printf("(a - b): %v\n", (a - b))
fmt.Printf("(a / b): %v\n", (a / b))
fmt.Printf("(a * b): %v\n", (a * b))
//fmt.Printf("(b % a): %v\n", (b % a))
c := b % 10
fmt.Printf("c: %v\n", c)
//++ --
a++
fmt.Printf("a: %v\n", a)
b--
fmt.Printf("b: %v\n", b)
}
/*
a: 10
b: 21
(a + b): 31
(a - b): -11
(a / b): 0
(a * b): 210
c: 1
a: 11
b: 20
*/
Golang中的选择结构
if else语句
package main
import "fmt"
func main() {
a := 18
if a > 18 {
fmt.Println("成年")
} else {
fmt.Println("未成年")
}
}
Go语言不同于其他的语言,它可以在if语句中定义变量:
package main
import "fmt"
func main() {
if a := 18; a > 18 {
fmt.Println("成年")
} else {
fmt.Println("未成年")
}
}
if else if语句
package main
import "fmt"
func main() {
if a := 18; a > 18 {
fmt.Println("成年")
} else if a < 18 {
fmt.Println("未成年")
} else {
fmt.Println("18岁")
}
}
switch结构
package main
import "fmt"
func f1() {
var day int
fmt.Scan(&day)
switch day {
case 1, 2, 3, 4, 5: //只要匹配到一个值就可以
fmt.Println("work day")
case 6, 7:
fmt.Println("relax")
default:
fmt.Println("输入出错")
}
}
func main() {
f1()
}
在Go语言中,不需要使用break
package main
import "fmt"
func f1() {
score := 60
//当switch后面什么都不写的时候,默认为true
switch {
case score >= 60:
fmt.Println("及格")
case score > 70 && score <= 100:
fmt.Println("优秀")
default:
fmt.Println("不及格")
}
}
func main() {
f1()
}
fallthrough(穿漏)
package main
import "fmt"
func f1() {
score := 100
switch score {
case 100:
fmt.Println("100")
fallthrough //加上fallthrough的时候,会继续向下执行
case 200:
fmt.Println("200")
case 300:
fmt.Println("300")
}
}
func main() {
f1()
}
Go语言中switch语句的注意事项
支持多条件匹配
不同的case之间不使用break分割,默认只会执行一个case
如果想要执行多个case,需要使用fallthrough关键字,也可以用break终止
分支还可以使用表达式,例如a>10
Go语言中的for循环
//格式还是和其他的语言是一样的,只不过不需要加上括号
package main
import "fmt"
func f1() {
// i := 1
// for i <= 10 {
// fmt.Printf("i: %v\n", i)
// i++
// }
for i := 1; i <= 10; i++ {
fmt.Printf("i: %v\n", i)
}
}
func main() {
f1()
}
for range循环
Go语言中可以使用for range遍历数组、切片、字符串、map以及通道。通过for range遍历的返回值具有以下的规律:
数组、切片、字符串返回索引和值
map返回键和值
通道只返回通道内的值
package main
import "fmt"
func f() {
var a = [...]int{1, 2, 3, 4, 5, 6} //当[]内什么都不写的时候,就是切片
// for i, v := range a {
// fmt.Printf("i: %v\tv: %v\n", i, v)
// }
//还可以直接输入forr,快捷键
for _, v := range a {
fmt.Printf("v: %v\n", v)
}
}
func main() {
f()
}
package main
import "fmt"
func f() {
m := make(map[string]string, 0)
m["name"] = "Y4y17"
m["age"] = "23"
m["email"] = "Y4y17@email.com"
for key, value := range m {
fmt.Printf("key: %v\tvaule: %v\n", key, value)
}
}
func main() {
f()
}
Go语言中的跳转语句
break
break除了在switch 和 for循环中去使用,还可以在标签中使用:
package main
import "fmt"
func f() {
MYLABEL:
for i := 0; i < 10; i++ {
fmt.Printf("i: %v\n", i)
if i >= 5 {
break MYLABEL
}
}
fmt.Println("END")
}
func main() {
f()
}
continue
package main
import (
"fmt"
)
func f1() {
for i := 0; i < 10; i++ {
MYLABLE:
for j := 0; j < 10; j++ {
if i == 2 && j == 2 { //跳过i=2 j=2的情况
continue MYLABLE
}
fmt.Printf("%v:%v\n", i, j)
}
}
}
func f() {
for i := 0; i < 10; i++ {
if i == 2 {
continue
} else {
fmt.Printf("i: %v\n", i)
}
}
}
func main() {
// f()
f1()
}
goto
goto语句常用于跳出多层循环
package main
import (
"fmt"
)
func f2() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if i == 2 && j == 2 { //当i=2 j=2的时候,直接跳出两个循环,跳到END继续运行
goto END
}
fmt.Printf("%v:%v\n", i, j)
}
}
END:
fmt.Printf("end...")
}
func main() {
f2()
}
Go语言中的数组
定义和初始化
package main
import "fmt"
func test1() {
//数组的定义
var a1 [2]int
var a2 [3]string
var a3 [2]bool
fmt.Printf("a1: %T\n", a1)
fmt.Printf("a2: %T\n", a2)
fmt.Printf("a3: %T\n", a3)
//数组的初始化
var a4 = [2]int{3, 4}
var a5 = [2]string{"Y4y17", "hello"}
var a6 = [2]bool{true, false}
fmt.Printf("a4: %v\n", a4)
fmt.Printf("a5: %v\n", a5)
fmt.Printf("a6: %v\n", a6)
var a7 = [...]int{7, 8, 9}
fmt.Printf("len(a7): %v\n", len(a7))
//根据索引进行赋值
var a8 = []int{0: 1, 5: 9}
var a9 = []string{1: "Y4y17", 8: "hello"}
fmt.Printf("a8: %v\n", a8)
fmt.Printf("a9: %v\n", a9)
}
func main() {
test1()
}
数组的遍历
package main
import "fmt"
func test1() {
var a = [5]int{1, 2, 3, 4, 6}
for i := 0; i < len(a); i++ {
fmt.Printf("a[%v]: %v\n", i, a[i])
}
}
func test2() {
var str = [4]string{"Y4y17", "hello", "world", "7777"}
for i, v := range str { //其中i代表的是索引值,v代表的就是str[i]
//如果不想使用i(索引值),那么我们可以将i修改为下划线(_)
fmt.Printf("str[%v]: %v\n", i, v)
}
}
func main() {
test1()
fmt.Printf("-----------\n")
test2()
}
输出结果如下:
Go语言中的切片
切片的声明
package main
import "fmt"
func test1() {
//切片的声明
var list1 []int
fmt.Printf("list1: %v\n", list1)
var list2 = make([]int, 2)
fmt.Printf("list2: %v\n", list2)
//切片的初始化
var list3 = []int{1, 2, 3}
fmt.Printf("list3[1]: %v\n", list3[1])
//输出list2的长度和容量
fmt.Printf("len(list2): %v\n", len(list2))
fmt.Printf("cap(list2): %v\n", cap(list2))
}
func main() {
test1()
}
切片的初始化
针对切片的切分遵循:左闭右开 即 [ )
package main
import "fmt"
func test1() {
//第一种初始化
var list1 = []int{1, 2, 3, 4}
fmt.Printf("list1: %v\n", list1)
//第二种初始化
//利用数组进行初始化
var a = [...]int{1, 2, 3, 4, 5, 6}
list2 := a[2:5]
fmt.Printf("list2: %v\n", list2)
list3 := a[2:]
fmt.Printf("list3: %v\n", list3)
list4 := a[:]
fmt.Printf("list4: %v\n", list4)
list5 := a[:5]
fmt.Printf("list5: %v\n", list5)
}
func main() {
test1()
}
切片的遍历
同样切片的遍历和数组的遍历类似,存在两种遍历的方式:
package main
import "fmt"
func test1() {
var list1 = []int{1, 2, 3, 4, 5, 6}
for i := 0; i < len(list1); i++ {
fmt.Printf("list1[%v]: %v\n", i, list1[i])
}
}
func test2() {
var list1 = []int{1, 2, 3, 4, 5, 6}
for i, v := range list1 {
fmt.Printf("i:%v v: %v\n", i, v)
}
}
func main() {
// test1()
test2()
}
切片的增删改查
package main
import "fmt"
//add
func add() {
var list = []int{1, 3, 2, 5, 99}
list = append(list, 100)
fmt.Printf("list: %v\n", list)
}
//delete
func delete() {
var list = []int{1, 2, 3, 4, 5, 6, 7}
list = append(list[:3], list[4:]...) //删除索引为3的元素
fmt.Printf("list: %v\n", list)
}
//update
func update() {
var list = []int{1, 2, 3, 4, 5, 6, 7}
list[4] = 777
fmt.Printf("list: %v\n", list)
}
//query
func query() {
var list = []int{1, 2, 3, 4, 5, 6, 7}
key := 5
for _, v := range list {
if key == v {
fmt.Printf("v: %v\n", v)
}
}
}
//copy函数的用法
func test() {
var list = []int{1, 2, 3, 4}
var list2 = make([]int, 4)
copy(list2, list)
// fmt.Printf("list: %v\n", list)
fmt.Printf("list2: %v\n", list2)
}
func main() {
//add()
// delete()
// update()
//query()
test()
}
Go语言中的map
map是一种无序的键值对的集合;最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值;
两种定义map的方式:
一种是通过内建函数make
另一种是通过map关键字来定义Map
package main
import "fmt"
func test2() {
map1 := map[string]string{"name": "Y4y17", "age": "23", "email": "xxx.com"}
for _, v := range map1 {
fmt.Printf("v: %v\n", v)
}
}
func test1() {
//map的声明
var map1 map[string]string
//创建集合
map1 = make(map[string]string)
//map 插入key-value对
map1["name"] = "Y4y17"
map1["age"] = "23"
map1["email"] = "xxx.com"
//使用键来输出map值
for site := range map1 {
fmt.Println(site, "---->", map1[site])
}
v, ok := map1["name"]
fmt.Printf("v: %v\n", v)
fmt.Printf("ok: %v\n", ok)
v, ok = map1["ages"]
fmt.Printf("v: %v\n", v)
fmt.Printf("ok: %v\n", ok)
}
func main() {
test1()
}