go基础2

go语法基本使用

包的管理

# 就是模块的意思
1.自定义包
	go语言的代码必须放在gopath的src的路径下
	包的导入是从gopath的src路径下开始检索的
	除了main包以外,建议包的名字就叫文件夹的名字
	同一个包下,变量和函数只能定义一次
	同一个包下的变量和函数可以直接使用
	包内的函数或变量,想让外部函数使用,必须首字母大写
	以后下的第三方包就放在fopath的src下
-day1
	-day2
		-s1.go
            package day2
            import "fmt"
			func init(){
	fmt.Println("我是day2中的初始函数")
}
            func Test(){
                fmt.Println("我是day2下面的test函数")
                fmt.Println(Name)

            }
		-s2.go
			package day2
			import "fmt"

			var Name = "zc"
            func Test1() {
                fmt.Println("我是day2下面的test1函数")
                fmt.Println(Name)

            }

	-s1.go
        package main
        import (
            "day01/day2"
            "fmt"
        )

        func main() {
            day2.Test()
            fmt.Println(day2.Name)
        }	
func init(){
	fmt.Println("我是day2中的初始函数")
}
在包里面的go文件中定义这个初始函数,在一开始导报的时候就开始执行,并且可以定义多个.
初始化一些操作


包导入的几种方式
	-import "day02/mypackage"
    -给包重命名
    	-import 名字 "day02/mypackage"
        名字.变量/函数
    -包只导入,不使用
    import _ "day02/mypackage"

go mod的使用

go语言没有一个统一包管理地址,大家都放在到github上面

go mod模式的使用

两种创建的方式
	-set GO111MODULE=on
	-命令行下输入:go mod init 项目名   在当前路径下创建出go.mod(该项目依赖go的版本,第三方包版本)
	-在goland IDE设置里面settings->go Modules里配置 GOPROXY=https://goproxy.cn 这样就可以下载快点
	- go get -u github.com/astaxie/beego 下载beego框架


go.mod中加入依赖
        -以后把项目copy给别人,go install
        -自己写的包,就放在自己项目路径下
        -加代理的方式:手动写,goland中配置
   	-在goland中创建项目时,直接指定modules,可以配置环境变量(加代理)


条件语句

package main

import "fmt"

func main() {
	a:= Test()
	// if else
	//if a >10 {
	//	fmt.Println("a是大于10")
	//} else {
	//	fmt.Println("a小于10")
	//}
	// if - else if - else
	if a>10 {
		fmt.Println("a大于10")
	} else if a==10{
		fmt.Println("a等于10")
	} else {
		fmt.Println("a小于10")

	}

}
func Test() int {
	return 100
}

循环

没有while,do while 循环,只有一个for循环

package main

import "fmt"

//for 变量初始化;条件 变量自增/自减{}
func main() {
	for i:=0;i<10;i++{
		fmt.Println(i)
	}

}

swicth

可以代替多条件if语句

package main

import "fmt"

func main() {
	num:=2
	switch num {
	case 1,2,3:
		fmt.Println("1")
        fallthrough
	case 4,5:
		fmt.Println('2')
	default:
		fmt.Println("错误提示")
	}
}
fallthrough:只要看到这个,无条件执行下一个case或者default

数组

是同一类元素的集合,是值类型

package main

import "fmt"

//数组就是同一类元素的集合,可以多个值,但是

func main() {
	//定义大小为三的string类型数据,
	//var name [3]string
	//var ages [3]int8
	//ages[0] = 99
	//ages[1] = 88
	//ages[2] = 77
	//fmt.Println(ages)
	//定义初始化
	//var ages [3]int=[3]int{1,2,3}
	//var ages=[3]int{1,2,3}
	//ages:=[3]int{1,2,3} // 不能多放
	//fmt.Println(ages)

	//数组的其他用法
	var ages = [...]int{1, 2, 3, 4, 5, 6, 7} // 数据里面的元素是多少个,他的大小就是多少
	fmt.Println(ages)
	test(ages) // 因为数组是值类型, 所有函数传参,都是copy传递
	fmt.Println(ages)

}
func test(ages [7]int){
	ages[0]=99
	fmt.Println(ages)
}

//[1 2 3 4 5 6 7]
//[99 2 3 4 5 6 7]
//[1 2 3 4 5 6 7]

数组的循环

var ages = [...]int{1, 2, 3, 4, 5, 6, 7} // 数据里面的元素是多少个,他的大小就是多少
	//数组的长度,在定义阶段已经固定
	//fmt.Println(len(ages))
	//方式一
	for i := 0; i < len(ages); i++ {
		fmt.Println(ages[i])
	}
	//方式二
	for i:=range ages{
		fmt.Println(i)//打印出来的是索引
	}
	for _,value:=range ages{
		fmt.Println(value)
	}//打印出来值


多维数组

a := [3][3]int{{1, 2, 3}, {2, 3, 4}, {3, 4, 5}}
	for _, value := range a {
		for _, li := range value {
			fmt.Println(li)
		}
	}

数组的定义并初始化

a := [...]int{10:99}
	fmt.Println(a)//指定位置初始化

切片

数组看上去比较灵活,但是他有固定的长度限制,不能增加他的长度,所以要用切片

切片是由数组建立的一种方便,灵活且强大的包装,切片本身不能拥有任何数据,他们只是对现有数组的引用,就是指针指向了某个数组

package main

import "fmt"

func main() {
	//1.切片的第一种方式
	//定义数组
	a := [...]int{1, 2, 3, 4, 5, 6, 7}
	//基于数组,做一个切片
	var b []int
	b = a[:] //[]int不带任何东西就是切片
	fmt.Println(b)
	fmt.Printf("%T", b)
	fmt.Printf("%T", a)

	//2.使用切片
	fmt.Println(b[0])

	//3.修改切片
	b[0]=999
	fmt.Println(b)
	//打印数组,数组会被修改,修改数组也会影响切片
	fmt.Println(a)
	//5.切片只切数组的一部分
	var c []int = a[3:5]
	fmt.Println(c)
   //7.切片的长度和容量
	fmt.Println(len(c))
	//容量,最多能存多少
	fmt.Println(cap(c))
	//8.切片追加值
	c = append(c, 6)
	c = append(c, 88)
	//到了临界点在追加
	c = append(c, 77)
	fmt.Println(c)
	fmt.Println(a) //到了临界点后追加的元素数组不会增加.

	fmt.Println(len(c))
	//容量,最多能存多少
	fmt.Println(cap(c)) //到了临界点之后会在原来的基础上翻倍,把原来的值copy到新的数组里面,就会脱离关系, 再去修改的话就不会改变

}
      
}
//切片可以继续切片

map

map 就是key-value数据结构,类似于集合

var map 变量名 map[keytype]valuetype

key:可以是bool,num,string, 指针,channel,我们常用的是int和string

声明:是不会分配内存的,初始化要make,分配内存后才能赋值和使用

package main

import "fmt"

func main() {
	//map的声明和注意事项

	//在使用map前,需要先make,make的作用是给map分配数据空间
    //赋值方式一
	a := make(map[string]string,10) //给他分配10个这样的内存空间
	a["No.1"] = "松江"
	a["No.2"] = "五十"
    //赋值方式二
    a := map[string]string{"No.1":"松江","No.2":"五十"}
	fmt.Println(a)
}
map[No.1:松江 No.2:五十]

练习


package main

import "fmt"

func main() {
	//存放三个学生信息,每个学生有name,sex
	studentMap :=make(map[string]map[string]string)
	studentMap["stuNo.1"] = make(map[string]string,2)
	studentMap["stuNo.1"]["name"] = "tom"
	studentMap["stuNo.1"]["sex"] = "男"
	fmt.Println(studentMap)

}
map[stuNo.1:map[name:tom sex:男]]

map的crud

//增加和更新
map["key"]=value key有就更新,没有就增加

//删除
delete(map,"key") delete是一个内置函数,如果key存在就删除,不存在运行也不会出错
delete(a,"No.2")
//查找
val, ok := a["No.1"]
	if ok {
		fmt.Printf("有No.1,val为%v",val)
	}else {fmt.Println("没有")}
//必须是ok

注意: 如果我们要删除map所有的key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除,或者map = make(...),make一个新的,让原来的成为垃圾,被gc回收

a := make(map[string]string) //给他分配10个这样的内存空间
a["No.1"] = "松江"
a["No.2"] = "五十"
a = make(map[string]string)
fmt.Println(a)

map的遍历

map的遍历我们使用for-range来遍历

for i, v := range a {
		fmt.Println(i, v)
	}

案例

package main

import "fmt"

func main() {
	studentMap :=make(map[string]map[string]string)
	studentMap["stuNo.1"] = make(map[string]string,2)
	studentMap["stuNo.1"]["name"] = "tom"
	studentMap["stuNo.1"]["sex"] = "男"
	studentMap["stuNo.2"] = make(map[string]string,2)
	studentMap["stuNo.2"]["name"] = "jack"
	studentMap["stuNo.2"]["sex"] = "女"
	studentMap["stuNo.3"] = make(map[string]string,2)
	studentMap["stuNo.3"]["name"] = "roll"
	studentMap["stuNo.3"]["sex"] = "男"
	for k1,v1 :=range studentMap{
		fmt.Println("k1=",k1)
		for k2, v2 := range v1{
			fmt.Println("\t",k2,v2)
		}
	}

}

map切片

使用一个map来记录monster的信息name和age,一个monster对应一个map,并且妖怪的个数可以动态的增加

package main

import "fmt"

func main() {
	//声明一个map切片
	//对切片进行make
	monsters := make([]map[string]string, 2)
	//if monsters[0] == nil {
	//	monsters[0] = make(map[string]string, 2)
	//	monsters[0]["name"] = "牛魔王"
	//	monsters[0]["age"] = "500"
	//}
	//if monsters[1] == nil {
	//	monsters[1] = make(map[string]string, 2)
	//	monsters[1]["name"] = "铁扇"
	//	monsters[1]["age"] = "500"
	//} //这样就是写死了,不能动态增加

	//我们需要使用到切片的append函数,可以动态的增加monsters
	newMonsters := map[string]string{
		"name": "新的妖怪",
		"age":  "500",
	}
	monsters = append(monsters,newMonsters)

	fmt.Println(monsters)

}

map的排序

package main

import (
	"fmt"
	"sort"
)

func main() {
	//map的排序
	map1 := map[int]int{10: 100, 4: 90, 9: 12}
	fmt.Println(map1)
	//如果按照map 的key顺序进行排序输出
	//1. 先将map 的key放入切片中
	//2. 对切片排序
	//3. 遍历切片,按照key来输出map 的值
	// 定义一个切片
	var keys []int
	for k, _ := range map1 {
		keys = append(keys, k)
	}
	//排序
	sort.Ints(keys)
	fmt.Println(keys)
	for _,k:=range keys{
		fmt.Printf("map1[%v]=%v \n",k,map1[k])
	}

}

map使用细节

  • map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map

    
     package main
    
    import "fmt"
    
    func modify(map1 map[int]int) {
    map1[10] = 900
    }
    
    func main() {
    map1 := map[int]int{1: 90, 2: 288, 10: 88}
    modify(map1)
    fmt.Println(map1)
    
    }
    # map[1:90 2:288 10:900]
    
  • map 的容量达到后,在想map增加元素,会自动扩容,不会发生panic,map能自动增长键值对

    package main
    
    import "fmt"
    
    func modify(map1 map[int]int) {
    	map1[10] = 900
    }
    
    func main() {
    	map1 := make(map[int]int,2)
    	map1[1]=1
    	map1[2]=1
    	map1[3]=1
    	map1[10]=1
    
    	modify(map1)
    	fmt.Println(map1)
    
    } 
    
  • map的value也经常使用struct类型,更适合管理复杂的数据,如value为students 的结构体

    package main
    
    import "fmt"
    
    type Stu struct {
    	Name string
    	Age int
    	address string
    }
    func main() {
    	students := make(map[string]Stu,10)
    	stu1 := Stu{"tom",10,"北京"}
    	stu2 := Stu{"jack",101,"上海"}
    	students["No.1"] = stu1
    	students["No.2"] = stu2
    	fmt.Println(students)
    	for k,v := range students{
    		fmt.Printf("学生的编号%v \n",k)
    		fmt.Printf("学生的姓名%v \n",v.Name)
    		fmt.Printf("学生的编号%v \n",v.Age)
    		fmt.Printf("学生的编号%v \n",v.address)
    		fmt.Println("-----------")
    	}
    }
    ~!
    

综合使用案例

  • 使用map[string]map[string]string的类型

  • key表示用户名,是唯一的,不能重复

  • 如果某个用户名存在,就将密码修改成88888,不存在就增加这个用户的信息

  • 编写一个函数 modifyUser(users map[string]map[string]string,name string)完成上面的功能

    package main
    import "fmt"
    
      func modifyUser(users map[string]map[string]string, name string) {
      	//吸纳判断是否有name
      	//v,ok:=users[name]
      	if users[name] != nil {
      		users[name]["pwd"] = "888888"
      	} else {
      		//没有这个用户
      		users[name] = make(map[string]string, 2)
      		users[name]["pwd"] = "888888"
      		users[name]["nickname"] = "昵称" + name
    
      	}
      }
      func main() {
      	users := make(map[string]map[string]string, 10)
      	users["smith"] = map[string]string{"pwd":"9999","nickname":"xxxx"}
      	modifyUser(users, "tom")
      	modifyUser(users, "marry")
      	fmt.Println(users)
    
      }
    
posted @ 2021-01-20 21:52  小子,你摊上事了  阅读(42)  评论(0编辑  收藏  举报