首页 > 其他分享 >Go_day03

Go_day03

时间:2022-11-09 18:00:13浏览次数:29  
标签:map day03 s2 fmt Println int Go s1

Go基础语法

数组

数组是具有相同唯一类型的一组以编号且长度固定的数据项序列。类型可以是任意基本类型或者自定义类型。

数组一旦被定义后,大小不能被改变

func main() {
   //定义一个数组
   var nums [4]int

   //数组的下标从0开始
   nums[0] = 1
   nums[1] = 2
   nums[2] = 3
   nums[3] = 4

   fmt.Printf("%T\n", nums)
   //通过下标获取数组元素
   fmt.Println(nums[0])
   fmt.Println(nums[3])

   //获取数组的长度
   fmt.Println(len(nums))
   //获取数组的容量
   fmt.Println(cap(nums))
   //数组的大小固定 所以长度和容量是相同的

}

数组初始化

func main() {
   //常规的初始化
   var arr1 = [4]int{1, 2, 3, 4}
   fmt.Println(arr1)

   //快速定义数组
   arr2 := [4]int{5, 6, 7, 8}
   fmt.Println(arr2)

   //在不确定数组有多大下 可以是使用...定义长度
   //编译器会根据传入的元素推断数据的长度
   arr3 := [...]int{2, 3, 12, 3, 67, 4} //数组是可以有重复元素存在呦
   fmt.Println(arr3)
   fmt.Println(len(arr3))
   fmt.Println(cap(arr3))

   //初始化时也可以根据下标指定位置赋值
   arr4 := [4]int{1: 34, 0: 100, 3: 45}
   fmt.Println(arr4)
}

数组的遍历

func main() {
   var arr = [5]int{1, 2, 3, 4, 5}

   for i := 0; i < len(arr); i++ {
      fmt.Println(arr[i])

   }

   //i下标 v元素值
   for i, v := range arr {
      fmt.Println(i, v)
   }
}

数组是值传递类型

func main() {
   num := 10
   fmt.Printf("%T\n", num)

   arr1 := [5]int{1, 2, 3, 4, 5}
   fmt.Printf("%T\n", arr1)

   arr2 := [3]string{"ni", "hao"}
   fmt.Printf("%T\n", arr2)
   fmt.Println(arr2)

   //数组是值传递类型
   num2 := num            //将num的值赋予ynum2
   fmt.Println(num, num2) //10 10
   num2 = 100             //改变num2的值
   fmt.Println(num, num2) //10 100 num的值未改变  说明是值传递

   arr3 := arr1
   fmt.Println(arr1) //1 2 3 4 5
   fmt.Println(arr3) //1 2 3 4 5
   arr3[0] = 100     //改变arr3 第一个元素的值
   //arr3只是arr1的拷贝  arr3的改变不会影响arr1
   fmt.Println(arr1) //1 2 3 4 5 //没有被改变
   fmt.Println(arr3) //100 2 3 4 5

}

数组的排序

func main() {

   /*
         一堆书 34 12 4 1 88  按照相邻两个比较 得出 从大到小排序
         1、34 12 4 88 1   4
         2、34 12 88 4 1   3
         3、34 88 12 4 1   2
         4、88 34 12 4 1   1
      ps:总共比较了4轮

         同理34 12 4 1 88  从小到大
         1、12 4 1 34 88
         2、4 1 12 34 88
         3、1 4 12 34 88





   */

   arr := [...]int{34, 12, 4, 1, 88}
   sort(arr)

}

func sort(arr [5]int) {
   for i := 1; i < len(arr); i++ {
      for j := 0; j < len(arr)-i; j++ {
         if arr[j] < arr[j+1] {
            arr[j], arr[j+1] = arr[j+1], arr[j]
         }
      }
      fmt.Println(arr)
   }
}

多维数组

func main() {
   var name [2][2]int
   name[0][0] = 1
   fmt.Println(name)

   var arrs = [3][4]int{
      {1, 2, 3, 4},
      {5, 6, 7, 8},
      {9, 10, 11, 12},
   }

   fmt.Println(arrs)

   //二维数据遍历
   for i := 0; i < len(arrs); i++ {
      for j := 0; j < len(arrs[i]); j++ {
         fmt.Printf("%d ", arrs[i][j])
      }
      fmt.Println()
   }

   for _, v := range arrs {
      //fmt.Println(i, v)
      for _, v2 := range v {
         fmt.Println(v2)
      }
   }
}

切片

  • 切片的长度是不固定的
  • 可以追加元素,容量也会随之增大
  • 切片本身是没有数据的,都是对现有数据的引用
  • 所以切片是引用传递
func main() {
   //数组 类型是 [5]int的长度一旦被确定就不可改变
   var arr = [5]int{1, 2, 3}
   fmt.Printf("%T\n", arr)
   fmt.Println(arr)

   //定义一个切片 类型是[]int,他的长度是可变的 默认值为空[] 空的关键子是nil
   var s1 []int
   fmt.Printf("%T\n", s1)
   fmt.Println(s1)
   if s1 == nil {
      fmt.Println("切片为空")
   }

   var s2 = []int{1, 2, 5}
   fmt.Println(s2)
   //所以区分切片与数组的类型在于 [] 数据类型 中括号是否为空

   //下面测试一下切片的传递类型
   fmt.Println("==========================")
   fmt.Println("s2的元素值:", s2) //1 2 5
   s3 := s2
   s3[1] = 4
   fmt.Println("s2的元素值:", s2) //1 4 5
   fmt.Println("s3的元素值:", s3) //1 4 5

   //这里可以发现只改变了s3的元素值,但s2也随之改变 说明 s2与s3指向的是同一个地址 切片是引用传递
}

使用make创建切片

/*
使用make函数创建切盼
语法:make([]T,length,capacity) (类型,长度,容量)
长度是当前有多少个元素,容量是当前最大能够容纳多少元素
*/

func main() {
   s1 := make([]int, 5, 10)
   fmt.Println(s1)
   fmt.Println("s1的长度:", len(s1)) //长度5
   fmt.Println("s1的容量:", cap(s1)) //容量10
   s1[1] = 100
   s1[9] = 900 //这里会报错  虽然最大容量是10 但还是只能操作5个
   fmt.Println(s1)
}
  • 实际生效的还是长度,可操作的元素也在长度中

切片扩容

  • 通过是append可以扩容切片
  • 在append中可以使用 切片... 展开切片相当于 取出所有的元素的缩写
s2 := make([]int, 0, 5)
//s2[0]=1//长度为0 无法操作
fmt.Println(s2)
//使用append扩容
s2 = append(s2, 1, 2)
fmt.Println(s2)
//如果追加的元素个数超出容量,那么切片就会自动扩容
s2 = append(s2, 3, 4, 5, 6, 7)
fmt.Println(s2, cap(s2)) //容量10

s3 := []int{6, 6, 6, 6, 6, 6}
s2 = append(s2, s3...)   //在append 中使用”切片...“就可以吧元素都取出来
fmt.Println(s2, cap(s2)) //容量20

fmt.Println("for循环遍历s2")
for i := 0; i < len(s2); i++ {
   fmt.Printf("%d ", s2[i])
}

fmt.Println("forr遍历s2")
for i, v := range s2 {
   fmt.Printf("%d:%d\n", i, v)
}
  • 切片底层其实是引用了数组
  • 每一次扩容,引用的地址会随之变化也就是说底层重新创建了一个数组,新的数组copy了原来数组的元素,切片的引用也会指向新数组
  • 每次扩容超出了原先切片的容量 容量就是2倍增长
func main() {

   s1 := []int{1, 2, 3}
   fmt.Printf("容量:%d 长度:%d\n", cap(s1), len(s1))
   fmt.Printf("地址:%p\n", s1) //地址:0xc0000aa078

   s1 = append(s1, 4, 5)
   fmt.Printf("容量:%d 长度:%d\n", cap(s1), len(s1))
   fmt.Printf("地址:%p\n", s1) //地址:0xc0000c8030

   s1 = append(s1, 6)
   fmt.Printf("容量:%d 长度:%d\n", cap(s1), len(s1))
   fmt.Printf("地址:%p\n", s1) //地址:0xc0000c8030

   s1 = append(s1, 7, 8)
   fmt.Printf("容量:%d 长度:%d\n", cap(s1), len(s1))
   fmt.Printf("地址:%p\n", s1) //地址:0xc000086060

}

经常会见到: p . p , &p 三个符号
p是一个指针变量的名字,表示此指针变量指向的内存地址,如果使用%p来输出的话,它将是一个16进制数。而
p表示此指针指向的内存地址中存放的内容,一般是一个和指针类型一致的变量或者常量。
而我们知道,&是取地址运算符,&p就是取指针p的地址。等会,怎么又来了个地址,它到底和p有什么区别?区别在于,指针p同时也是个变量,既然是变量,编译器肯定要为其分配内存地址,就像程序中定义了一个int型的变量i,编译器要为其分配一块内存空间一样。而&p就表示编译器为变量p分配的内存地址,而因为p是一个指针变量,这种特殊的身份注定了它要指向另外一个内存地址,程序员按照程序的需要让它指向一个内存地址,这个它指向的内存地址就用p表示。而且,p指向的地址中的内容就用*p表示

通过数组创建切片

func main() {

   arr := [6]int{1, 2, 3, 4, 5, 6}
   fmt.Println(arr)
   //通过数组创建切片
   //arr[start:end] 包含start 但不包含end
   s1 := arr[:5] //下标0-4
   fmt.Println(s1)
   s2 := arr[2:4] //下标2-3
   fmt.Println(s2)
   s3 := arr[0:2] //下标0-1
   fmt.Println(s3)
   s4 := arr[:] //全部
   fmt.Println(s4)
}

切片是引用传递类型

func main() {
   s1 := []int{1, 2, 3, 4}
   s2 := s1
   fmt.Println(s1, s2)
   s2[0] = 100
   fmt.Println(s1, s2)
   fmt.Printf("%p\n", s1)
   fmt.Printf("%p\n", s2)
}

深拷贝与浅拷贝

深拷贝就是 将数值完全拷贝一份传入 等同值传递

浅拷贝 将引用地址拷贝 等同引用传递

func main() {
   s1 := []int{1, 2, 3, 4}
   s2 := make([]int, 0, 0)
   //var s2 []int
   //借助for循环实现深拷贝
   for i := 0; i < len(s1); i++ {
      s2 = append(s2, s1[i])
   }
   fmt.Println(s1, s2)
   fmt.Printf("%p\n", s1)
   fmt.Printf("%p\n", s2)

   //通过copy实现深拷贝
   s3 := []int{5, 6}
   copy(s1, s3) //copy(des,app) des是目标片 被修改的  app是修改的内容切片 不会动
   fmt.Println(s1, s3)
   fmt.Printf("%p\n", s1)
   fmt.Printf("%p\n", s3)

}

Map

  • 是一种无序的键值对集合
  • 可以通过key来快速检索数据
  • key相当于索引,value就是key指向的值
  • 是引用类型

map的初始化

func main() {
   //map类型的定义,map[key]value
   var map1 map[int]string //没有内容 是nil 还未被创建
   var map2 = make(map[int]string) //通过make方式是被创建的 有内容是map[]
   var map3 = map[string]int{"GO": 100, "JAVO": 90}

   if map1 == nil {
      fmt.Println("win")
   }
   fmt.Println(map1)
   if map2 == nil {
      fmt.Println("win")
   }
   fmt.Println(map2)
   if map3 == nil {
      fmt.Println("win")
   }
   fmt.Println(map3)

}
  • map中的key不可重复,添加重复的map是 新的value会将老的value覆盖

map的使用

func main() {
   //创建map
   var map1 map[int]string     //这里只是声明有map1这个变量的存在并没有为其分配值空间
   map1 = make(map[int]string) //需要通过make来创建map[]
   map1[1] = "GO"
   map1[2] = "JAVA"
   map1[3] = "PYTHON"
   fmt.Println(map1)

   //获取map中的数据
   fmt.Println(map1[1]) //根据key值获取value值
   fmt.Println(map1[4]) //key不存在 则会获取默认的零值 ”“

   //可以通过map的一些属性值ok-idiom判断key是否存在
   s, ok := map1[1]
   if ok {
      fmt.Println("key值存在,value", s)
   } else {
      fmt.Println("key值不存在,value", s)
   }

   //修改map的value
   map1[1] = "GoLan"
   fmt.Println(map1)

   //删除数据
   delete(map1, 1)
   fmt.Println(map1)

   fmt.Println(len(map1))
   map1[1] = "GO"
   fmt.Println(map1)
   fmt.Println(len(map1))
   //key存在就是修改,不存在就是添加

}

map的遍历

func main() {
   var map1 = map[int]string{100: "go", 90: "java", 80: "python"}
   for i := range map1 {
      fmt.Println(i, map1[i])
   }
   for i, v := range map1 {
      fmt.Println(i, v)
   }

   //引用传递哦
   map2 := map1
   map2[100] = "GOLAN"
   fmt.Println(map1)
   fmt.Println(map2)
}
/*
   需求:
      创建map来存储人的name、age、sex、addr信息
      每个map存以一个人的信息
      通过切片存入map
      再按照标准name age sex addr顺序打印输出
*/

func main() {
   var info map[string]string
   info = make(map[string]string)
   info["name"] = "xue"
   info["age"] = "18"
   info["sex"] = "nan"
   info["addr"] = "china"

   info2 := make(map[string]string)
   info2["name"] = "zhangsan"
   info2["age"] = "20"
   info2["sex"] = "nan"
   info2["addr"] = "hangzhou"

   info3 := map[string]string{"name": "lisi", "age": "24", "sex": "nan", "addr": "sichuan"}

   //fmt.Println(info)
   //fmt.Println(info2)
   //fmt.Println(info3)

   infoData := make([]map[string]string, 0, 3)
   infoData = append(infoData, info)
   infoData = append(infoData, info2)
   infoData = append(infoData, info3)

   for _, v := range infoData {
      fmt.Printf("name:%s\n", v["name"])
      fmt.Printf("age:%s\n", v["age"])
      fmt.Printf("sex:%s\n", v["sex"])
      fmt.Printf("addr:%s\n", v["addr"])
      fmt.Println()
   }
}

练习

/*
   需求:
      创建map来存储人的name、age、sex、addr信息
      每个map存以一个人的信息
      通过切片存入map
      再按照标准name age sex addr顺序打印输出
*/

func main() {
   var info map[string]string
   info = make(map[string]string)
   info["name"] = "xue"
   info["age"] = "18"
   info["sex"] = "nan"
   info["addr"] = "china"

   info2 := make(map[string]string)
   info2["name"] = "zhangsan"
   info2["age"] = "20"
   info2["sex"] = "nan"
   info2["addr"] = "hangzhou"

   info3 := map[string]string{"name": "lisi", "age": "24", "sex": "nan", "addr": "sichuan"}

   //fmt.Println(info)
   //fmt.Println(info2)
   //fmt.Println(info3)

   infoData := make([]map[string]string, 0, 3)
   infoData = append(infoData, info)
   infoData = append(infoData, info2)
   infoData = append(infoData, info3)

   for _, v := range infoData {
      fmt.Printf("name:%s\n", v["name"])
      fmt.Printf("age:%s\n", v["age"])
      fmt.Printf("sex:%s\n", v["sex"])
      fmt.Printf("addr:%s\n", v["addr"])
      fmt.Println()
   }
}

标签:map,day03,s2,fmt,Println,int,Go,s1
From: https://www.cnblogs.com/onlyxue/p/16874695.html

相关文章

  • GO语言实战-小程序或公众号接口gin框架验证微信服务器消息签名
    在开发GO小程序或者公众号接口的时候,需要对接微信消息的token签名验证,这时候需要开发者验证来自微信,并返回指定的字符串微信文档里给的是PHP版本的代码,下面这个......
  • 大数据开发:Go中的方法
    我们知道Go中没有继承,接口的用法也与Java中的用法大相径庭,很多适合,我们需要使用OO的思想来组织我们达到项目,但是将Java的oo思想在Go中会比较痛苦,Go中的方法和面向对象的类......
  • 0009.Django请求与响应
    HttpRequest对象服务器接受到http协议的请求后,会根据报文创建HttpRequest对象视图函数的第一个参数是HttpRequest对象在django.http模型中定义了HttpRequest对象的API......
  • django一些常用命令
    django一些常用命令#创建项目django-adminstartprojectmysite#创建app,创建成功项目以后,cd进入mysitepythonmanage.pystartappapp01#数据库迁移命令pythonmanage.p......
  • django-cors-headers实现跨域的方法总结
    django-cors-headers实现跨域的方法总结在setting.py中配置INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.cont......
  • Google团队开发的Guava工具包的代码示例
    上一篇​​java代码如何连接Linux虚拟机,还有文件上传下载,等基础命令​​一、项目源地址​​Github链接​​二、String操作2.1Join示例代码@Test//这个包引的是......
  • 传奇服务器CC gong ji 的原理、表现和防御策略,服务器防御
    一个好的DDOS必须是通过自己极少资源的消耗带来对方较大的资源消耗,否则比如ICMP-FLOOD和UDP-FLOOD都必须和别人一样大的带宽,对方服务器消耗多少资源自己也得赔上多少资源,效......
  • Golang常用框架
    :Gin、Iris、Beego、Buffalo、Echo、Revel,其中Gin、Beego和Iris较为流行。Iris是目前流行Golang框架中唯一提供MVC支持(实际上Iris使用MVC性能会略有下降)的框架,并且支持依赖......
  • django 模糊查询
    //查询welldata中welltype为空的记录result=welldata.objects.filter(welltype__isnull=True)result=welldata.objects.filter(welltype=None)//查询welldata中welltyp......
  • go excelize 批量写入数据到Excel
    funcCreateXlS(data[][]string,fileNamestring,headerNameArray[]string){f:=excelize.NewFile()sheetName:="sheet1"sheetWords:=[]strin......