1包
#1 包:模块的意思
#2 自定义包
-go语言的代码必须放在gopath的src路径下
-包导入是从gopath的src路径下开始检索(开始找)
-除了main包以外,建议包名就叫文件夹名,一个文件夹下的包名必须一致
-同一个包下,变量,函数只能定义一次
-同一个包下的变量和函数可以直接使用
-包内的函数或变量,想让外部包使用,必须首字母大写
-以后下的第三方包都是放在gopath的src路径下
# 3 init函数(特殊函数)
-不需要调用就会执行
-可以定义多个
# 4 包导入的几种方式
-import "day02/mypackage"
-给包重命名
-import 名字 "day02/mypackage"
名字.变量/函数
-包只导入,不使用
import _ "day02/mypackage"
# 5 go语言没有一个统一包管理的地址,大家都放到github上
# 6 采用go mode模式
-两种创建方式之一
-命令行下输入:go mod init 项目名 在当前路径下创建出go.mod(该项目依赖go的版本,第三方包版本)
-项目路径的cmd窗口,go get 第三方包,就会在go.mod中加入依赖
-以后把项目copy给别人,go install
-自己写的包,就放在自己项目路径下
-加代理的方式:手动写,goland中配置
-在goland中创建项目时,直接指定modules,可以配置环境变量(加代理)
2 if-else语句
package main
import "fmt"
//if-else
func main() {
//1 if else
a := test()
//if a>10{
// fmt.Println("a大于10")
//}else {
// fmt.Println("a小于10")
//}
//2 if --else if--- else
if a > 10 {
fmt.Println("dayu 10")
} else if a == 10 {
fmt.Println("10101010")
} else {
fmt.Println("xiaoyu 10")
}
//3 条件语句后不能回车换行
//if a > 10 {
// fmt.Println("dayu 10")
//} else if a == 10 {
// fmt.Println("10101010")
//} else {
// fmt.Println("xiaoyu 10")
//}
}
func test() int {
return 100
}
3 循环
package main
//for 循环
/* for 后面三部分,都可以省略
for 变量初始化;条件;变量自增/自减 {
循环体内容
}
*/
func main() {
//1 基本使用
//for i:=0;i<10;i++{
// fmt.Println(i)
//}
//2 省略第一部分
//i:=0 //作用域范围大,不止在for内部,外部也可以用
//for ;i<10;i++{
// fmt.Println(i)
//}
//2 省略第三部分
//i:=0 //作用域范围大,不止在for内部,外部也可以用
//for ;i<10;{
// fmt.Println(i)
// i++
//}
//3 省略一和三部分的简略写法(这就是while循环) for 条件{ 循环体内容}
//i:=0
//for i<10{
// fmt.Println(i)
// i++
//}
//4 死循环
//for {
// fmt.Println("ssssss")
//}
//5 只是演示开多协程
//for i:=0;i<4000;i++{
// go test2()
//}
//6 break :结束本次for循环,continue结束本次循环,继续下一次循环
}
//func test2() {
// for {
// fmt.Println("sssss")
// }
//
//}
4 switch语句
// switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。它可以被认为是替代多个 if else 子句的常用方式
package main
func main() {
//1 基本使用
//num:=4
//switch num {
//case 1:
// fmt.Println("1")
//case 2:
// fmt.Println("2")
//case 3:
// fmt.Println("3")
//case 4:
// fmt.Println("4")
//}
//2 默认情况
//num:=40
//switch num {
//case 1:
// fmt.Println("1")
//case 2:
// fmt.Println("2")
//case 3:
// fmt.Println("3")
//case 4:
// fmt.Println("4")
//default:
// fmt.Println("我没有匹配")
//}
//3 多表达式判断
//num:=40
//switch num {
//case 1,2,3,4,5,6,7,8:
// fmt.Println("1")
//case 10,11,16:
// fmt.Println("2")
//case 30:
// fmt.Println("3")
//case 40,44,45:
// fmt.Println("4")
//default:
// fmt.Println("我没有匹配")
//}
//4 无表达式的 switch
//num:=80
//switch {
//case num==12,num==13:
// fmt.Println("12,13")
//case num==40,num==41:
// fmt.Println("40,41")
//default:
// fmt.Println("我没有匹配")
//}
//5 Fallthrough
//num:=12
//switch {
//case num==12,num==13:
// fmt.Println("12,13")
// fallthrough
//case num==40,num==41:
// fmt.Println("40,41")
// //fallthrough //穿透,只要看到fallthrough,无条件执行下一个case或者default
//default:
// fmt.Println("我没有匹配")
//}
}
5数组
package main
import (
"fmt"
)
//数组:数组是同一类型元素的集合。可以放多个值,但是类型一致,内存中连续存储
// Go 语言中不允许混合不同类型的元素
func main() {
//1 数组的定义,数组的大小,在定义阶段就确定了,而且不能改
//定义了一个大小为3的string类型数组,里面可以放3个字符串
//var names [3]string
//var ages [3]int8
//fmt.Println(ages)
//2 数组赋值
//var ages [3]int8
//ages[0]=99
//ages[2]=88
//fmt.Println(ages)
//fmt.Println(ages[1])
//3 定义并初始化,
//var ages [3]int=[3]int{1,2,3}
//var ages [3]int=[3]int{1,2}
//var ages [3]int=[3]int{}
//var ages=[3]int{}
//ages:=[3]int{1,3,4,7} //不允许多放
//fmt.Println(ages)
//4 数组定义并初始化的其他(了解)数组只要定义,长度就固定了,。。。,后面放几个值,数组大小是多少
//var ages [9]int=[...]int{1,2,3,4,5,6,7,8} //不支持这个
//var ages =[...]int{1,2,3,4,5,6,7,8}
//ages :=[...]int{1,2,3,4,8}
//fmt.Println(len(ages))
//5 数组的大小是类型的一部分
//var a [2]int=[2]int{1,2}
//var b [2]int=[2]int{1,3}
//b=a //如果不是同一种类型,不允许相互赋值
//fmt.Println(b)
//6 数组是值类型
//var a [2]int=[2]int{1,2}
//fmt.Println(a)
//test5(a) //因为数组是值类型,go函数传参,都是copy传递,如果是值类型,函数内改了,不会影响原来的
//fmt.Println(a)
//7 数组长度 len() 数组长度在定义阶段已经固定
//var a [2]int=[2]int{1,2}
//fmt.Println(len(a))
//8 数组循环
//var a =[...]int{7,4,3,5,6,7}
//fmt.Println(a[99])
//fmt.Println(len(a))
//普通循环
//for i:=0;i<len(a);i++{
// fmt.Println(a[i])
//}
//通过range来循环 (range不是内置函数,是一个关键字,for,if,else),打印出索引
//for i:=range a{
// fmt.Println(i)
//}
//如果用一个变量来接收,这个值是可迭代的索引
//如果用两个变量来接收,这两个变量,一个是索引,一个具体的值
//for i,value:=range a{
// fmt.Println(i)
// fmt.Println(value)
//}
//把数组循环打印出来
//for _,value:=range a{
// fmt.Println(value)
//}
// 9 多维数组
//var a [3][3]int //定义
//a[0][1]=99 //使用
//fmt.Println(a)
//定义并赋初值
//var a [3][3]int=[3][3]int{{1},{1,2,3},{4,4,4}}
//var s =[3][3]string{{"lqz","xxx","yyy"},{},{}}
//fmt.Println(s)
//
////循环多维数组
//for _,value:=range s{
// for _,in_value:=range value{
// fmt.Println(in_value)
// }
//}
//10 数组定义并指定位置初始化
//var names [100]int=[100]int{10:99,99:99}
//var names [100]int=[100]int{10,11,2,44,99:99,45:88}
//fmt.Println(names)
}
func test5(a [2]int) {
a[0]=99
fmt.Println(a)
}
6 切片
package main
import "fmt"
//切片:切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用
func main() {
//1 切片定义的第一种方式
//定义一个数组
//var a =[10]int{9,8,7,6,5,4,3,2,1,0}
////基于数组,做一个切片
////[]int 中括号中不带东西,就是切片类型
//var b []int
//b=a[:]
//fmt.Println(b)
//fmt.Printf("%T",b)
//fmt.Println()
//fmt.Printf("%T",a)
//fmt.Println()
//
////2 使用切片
//fmt.Println(b[0])
//fmt.Println(b[1])
//
////3 修改切片,会影响数组
//b[0]=999
//fmt.Println(b)
////数组会被修改
//fmt.Println(a)
//
////4 修改数组,是否会影响切片?会
//a[3]=333
//fmt.Println(a) //数组
//fmt.Println(b) //切片
// 5 切片只切数组一部分
//var a =[10]int{9,8,7,6,5,4,3,2,1,0}
//var b []int=a[3:5]
//fmt.Println(b)
////修改切片
//b[0]=999
//fmt.Println(b)
//fmt.Println(a)
//a[4]=888
//fmt.Println(b)
//fmt.Println(a)
//6 当多个切片共用相同的底层数组时,每个切片所做的更改将反映在数组中
//var a =[10]int{9,8,7,6,5,4,3,2,1,0}
//var b []int=a[3:5]
//var c []int=a[4:6]
//fmt.Println(a)
//fmt.Println(b)
//fmt.Println(c)
//b[1]=555
//fmt.Println(a)
//fmt.Println(b)
//fmt.Println(c)
//7 切片的长度和容量
var a =[10]int{9,8,7,6,5,4,3,2,1,0}
//var b []int=a[3:5]
var b []int=a[7:8]
fmt.Println(a)
fmt.Println(b)
// 切片长度
fmt.Println(len(b))
// 切片容量(我最多能存多少值)
fmt.Println(cap(b))
//8 切片追加值
b=append(b,3)
b=append(b,999)
//到了临界点再追加
b=append(b,888)
fmt.Println(b)
fmt.Println(a)
fmt.Println(len(b))// 长度是4
fmt.Println(cap(b)) //容量是6
b[0]=111
fmt.Println(b)
fmt.Println(a)
}