Google资深工程师深度讲解Go语言-内建容器(三)[通俗易懂]

Google资深工程师深度讲解Go语言-内建容器(三)

大家好,又见面了,我是全栈君。

一数组

  1. 数量写在类型前面
  2. 可通过_省略变量
  3. 不仅range,任何地方都可通过_省略变量
  4. 如果只要i下标,可写成 for i:= range numbers
    package main
    
    import "fmt"
    
    func main() {
    	//定义数组的方法
    	var arr1 [5]int
    	arr2 := [3]int{1, 3, 5}
    	arr3 := [...]int{2, 4, 6, 8, 10}
    	var grid [4][5]int
    
    	fmt.Println(arr1, arr2, arr3) //[0 0 0 0 0] [1 3 5] [2 4 6 8 10]
    	fmt.Println(grid)             //4行5列 [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
    
    	//遍历:方法一
    	/*for i:=0; i<len(arr3);i++  {
    		fmt.Println(arr3[i])
    		//2
    		//4
    		//6
    		//8
    		//10
    	}*/
    
    	//方法二
    	//下标和键值都要
    	for i,v:=range arr3 {
    		fmt.Println(i,v)
    	}
    	//0 2
    	//1 4
    	//2 6
    	//3 8
    	//4 10
    
    	//只要键值
    	for _,v:=range arr3 {
    		fmt.Println(v)
    	}
    	//2
    	//4
    	//6
    	//8
    	//10
    
    	//只要下标
    	for i := range arr3 {
    		fmt.Println(i)
    	}
    	//0
    	//1
    	//2
    	//3
    	//4
    }
    

    为什么要用range?   

  •   意义明确美观
  •    c++ 没有类似能力
  • Java/Python:只能for each value,不能同时获取i,v

数组是值类型

  • int[10] 和int[20] 是不同类型
  • 调用func f(arr [10]int)会拷贝数组
  • 在go语言中一般不直接使用数组
    package main
    
    import "fmt"
    
    func printArray(arr *[5]int) {
    	arr[0] = 100
    	for i, v := range arr {
    		fmt.Println(i, v)
    	}
    }
    
    func main() {
    	//定义数组的方法
    	var arr1 [5]int
    	arr2 := [3]int{1, 3, 5}
    	arr3 := [...]int{2, 4, 6, 8, 10}
    	var grid [4][5]int
    
    	fmt.Println(arr1, arr2, arr3) //[0 0 0 0 0] [1 3 5] [2 4 6 8 10]
    	fmt.Println(grid)             //4行5列 [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
    
    	//遍历:方法一
    	/*for i:=0; i<len(arr3);i++  {
    		fmt.Println(arr3[i])
    		//2
    		//4
    		//6
    		//8
    		//10
    	}*/
    
    	//方法二
    	//下标和键值都要
    	/*for i,v:=range arr3 {
    		fmt.Println(i,v)
    	}*/
    	//0 2
    	//1 4
    	//2 6
    	//3 8
    	//4 10
    
    	//只要键值
    	/*for _,v:=range arr3 {
    		fmt.Println(v)
    	}*/
    	//2
    	//4
    	//6
    	//8
    	//10
    
    	//只要下标
    	/*for i := range arr3 {
    		fmt.Println(i)
    	}*/
    	//0
    	//1
    	//2
    	//3
    	//4
    	//数组是值类型
    	fmt.Println("arr1")
    	printArray(&arr1)
    
    	fmt.Println("arr3")
    	printArray(&arr3)//取地址后
    
    	fmt.Println("arr1 and arr3")
    	fmt.Println(arr1, arr3) //取指针后  [100 0 0 0 0] [100 4 6 8 10]
    
    	//printArray(arr2)
    
    }
    

     

二. slice 切片:

s:=[2:6] 半开半闭区间 ,s的值为[2,3,4,5]

package main

import "fmt"

func main() {
	arr := [...]int{0,1, 2, 3, 4, 5, 6}
	s := arr[2:6]
	fmt.Println("arr[2:6]", s) //切片半开半闭区间 arr[2:6] [2 3 4 5]
}

Google资深工程师深度讲解Go语言-内建容器(三)[通俗易懂]Google资深工程师深度讲解Go语言-内建容器(三)[通俗易懂]

package main

import "fmt"

func updateSlice(s []int) {
	s[0] = 100
}

func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6,7}
	//s := arr[2:6]
	//fmt.Println("arr[2:6]", s) //切片半开半闭区间 arr[2:6] [2 3 4 5]
	fmt.Println("arr[2:6]", arr[2:6]) // arr[开始下标:结束下标]
	fmt.Println("arr[:6]", arr[:6])
	s1 := arr[2:]
	fmt.Println("s1", arr[2:])
	s2 := arr[:]
	fmt.Println("s2", arr[:])

	fmt.Println("after update slice(s1)")
	updateSlice(s1)
	fmt.Println(s1)
	fmt.Println(arr)
	//after update slice
	//[100 33 4 5 6]
	//[0 1 100 33 4 5 6]

	fmt.Println("after update slice(s2)")
	updateSlice(s2)
	fmt.Println(s2)
	fmt.Println(arr)
	//after update slice(s2)
	//[100 1 100 33 4 5 6]
	//[100 1 100 33 4 5 6]
	fmt.Println("extending slice")
	arr[0],arr[2]=0,2
	s1=arr[2:6]
	s2=s1[3:5]
	fmt.Println("arr:",arr)//arr= [0 1 2 3 4 5 6 7]
	fmt.Println("s1:",s1)
	fmt.Println("s2:",s2)
	fmt.Println("--")
	fmt.Println("arr=",arr)
	fmt.Println("s1=%v,len(s1)=%d,cap(s1)=%d",s1,len(s1),cap(s1))//s1=%v,len(s1)=%d,cap(s1)=%d [2 3 4 5] 4 6
	fmt.Println("s2=%v,len(s2)=%d,cap(s2)=%d",s2,len(s2),cap(s2))//s2=%v,len(s2)=%d,cap(s2)=%d [5 6] 2 3
	fmt.Println(s1[3:6])// [5 6 7]
}

//arr[2:6] [2 33 4 5]
//arr[:6] [0 1 2 33 4 5]
//arr[2:] [2 33 4 5 6]
//arr[:] [0 1 2 33 4 5 6]

操作:

添加元素时如果超越cap,系统会重新分配更大的低层数组

由于值传递的关系,必须接受append的返回值

package main

import "fmt"

func printSlice(s []int) {
	fmt.Printf("%v,len=%d,cap=%d \n", s, len(s), cap(s))
}
func main() {
	fmt.Println("Create slice")
	var s []int
	for i := 0; i < 100; i++ {
		printSlice(s)
		s = append(s, 2*i+1)
	}
	fmt.Println(s)
	fmt.Println(len(s))//100

	s1 := []int{2, 4, 6, 8} [2 4 6 8],len=4,cap=4 
	s2 := make([]int, 16)//[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],len=16,cap=16 
	s3 := make([]int, 10, 32)//[0 0 0 0 0 0 0 0 0 0],len=10,cap=32 
	printSlice(s1)
	printSlice(s2)
	printSlice(s3)

	fmt.Println("copy slice")
	copy(s2, s1)
	printSlice(s2)
	//copy slice
	//[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0],len=16,cap=16
	
	fmt.Println("delete elements from slice")
	s2 = append(s2[:3], s2[4:]...)
	printSlice(s2)
	//delete elements from slice
	//[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0],len=15,cap=16 
	
	
	fmt.Println("popping  from  front")
	front := s2[0]
	s2 = s2[1:]
	fmt.Println(front)
	printSlice(s2)
	//popping  from  front
	//2
	//[4 6 0 0 0 0 0 0 0 0 0 0 0 0],len=14,cap=15 
	
	fmt.Println("popping  from back")
	tail := s2[len(s2)-1]
	s2 = s2[:len(s2)-1]
	fmt.Println(tail)
	printSlice(s2)
	//popping  from back
	//0
	//[4 6 0 0 0 0 0 0 0 0 0 0 0],len=13,cap=15 
}

三.map

   1.map的操作

  • 创建:make(map[string]int)
  • 获取元素:m[key]
  • key不存在时,获得value类型的初始值
  • 用value,ok:=m[key]来判断是否存在key
  • 用delete删除一个key

2.map的遍历

  • 使用range 遍历key,或者遍历key,value对
  • 不保证遍历顺序,如需顺序,需手动对key排序(借助slice)
  • 使用len获得元素个数

3.map的key

  • map使用哈希表,必须可以比较相等
  • 除了slice,map,function的内建类型都可以作为key
  • struct 类型不包含上述字段,也可作为key
package main

import "fmt"

func main() {
	//定义map3种方式
	m := map[string]string{
		"name":    "lxw",
		"course":  "golang",
		"site":    "imooc",
		"quality": "notbad",
	}
	m2 := make(map[string]int) //m2==empty map

	var m3 map[string]int //m3==nil

	fmt.Println(m, m2, m3)
	fmt.Println("==traversing map==")
	for k, v := range m {
		fmt.Println(k, v)
	}

	fmt.Println("---getting values---")
	courseName, ok := m["course"]
	fmt.Println(courseName, ok)

	//判断键是否存在
	if casseName, ok2 := m["caurse"]; ok2 {
		fmt.Println(casseName)
	} else {
		fmt.Println("key does not exist")
	}

	fmt.Println("--deleting values---")
	courseName, ok3 := m["name"]
	fmt.Println(courseName, ok3)

	delete(m, "name")
	courseName, ok3 = m["name"]
	fmt.Println(courseName, ok3)
}
/*map[course:golang name:lxw quality:notbad site:imooc] map[] map[]
==traversing map==
quality notbad
name lxw
course golang
site imooc
---getting values---
golang true
key does not exist
--deleting values---
lxw true
false*/
package main

import "fmt"
//最长不含有重复字符的子串
func lenthOfNonRepeatingSubstr(s string) int {
	lastOccurred := make(map[byte]int)
	start := 0
	maxLength := 0
	for i, ch := range []byte(s) {
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1
		}
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}
	return maxLength
}

func main() {
	fmt.Println(lenthOfNonRepeatingSubstr("abcabcbb")) //3
	fmt.Println(lenthOfNonRepeatingSubstr("bbbbb"))    //1
	fmt.Println(lenthOfNonRepeatingSubstr("pwwkew"))   //3
}

四.字符串

  • rune 相当于go的char;每个中文3个字节;
  • 使用range遍历pos,rune对
  • 使用utf8.RuneCountInString获得字符数量
  • 使用len获得字节长度
  • 使用[]byte获得字节

其他字符串操作

  • Fileds,split,join
  • Contains,Index
  • Tolower,toupper
  • Trim,trimRight,trimLeft
    //最长不含有重复字符的子串(国际版中英文都可以)
    package main
    
    import "fmt"
    //最长不含有重复字符的子串
    func lenthOfNonRepeatingSubstr(s string) int {
    	lastOccurred := make(map[rune]int)
    	start := 0
    	maxLength := 0
    	for i, ch := range []rune(s) {
    		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
    			start = lastI + 1
    		}
    		if i-start+1 > maxLength {
    			maxLength = i - start + 1
    		}
    		lastOccurred[ch] = i
    	}
    	return maxLength
    }
    
    func main() {
    	fmt.Println(lenthOfNonRepeatingSubstr("abcabcbb")) //3
    	fmt.Println(lenthOfNonRepeatingSubstr("bbbbb"))    //1
    	fmt.Println(lenthOfNonRepeatingSubstr("pwwkew"))   //3
    	fmt.Println(lenthOfNonRepeatingSubstr(""))//0
    	fmt.Println(lenthOfNonRepeatingSubstr("b"))//1
    	fmt.Println(lenthOfNonRepeatingSubstr("abcdef"))//6
    	fmt.Println(lenthOfNonRepeatingSubstr("这里是中国"))//5
    	fmt.Println(lenthOfNonRepeatingSubstr("一二三二一"))//3
    	fmt.Println(lenthOfNonRepeatingSubstr("黑化肥发灰会挥发灰化肥发挥会发黑"))//7
    }
    

     

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111729.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 可以搜课程设计的网站_课程设计论文格式

    可以搜课程设计的网站_课程设计论文格式1.主要功能:展示各种类型的作文。普通用户的登录注册和管理员用户登录。可以精确或模糊按照作文题目搜索。还有分页功能,首页、尾页、上一页、下一页。返回顶部等等很多功能。普通用户登录:发表作文,管理自己的作文,管理自己账号。管理员用户登录:发表作文,管理所有的作文,管理所有账号。数据库用的是sqlserver。丰富精美的css、js效果。2.效果截图:登录/注册没登录时的基础首页普通用户:左边的侧边栏可以随意显示隐藏。管理员:3.项目文件截图:

    2022年10月31日
  • PHP7中标量类型declare的用法详解

    PHP7中标量类型declare的用法详解

    2021年10月30日
  • Jetson TX1开发笔记(一):开机设置与刷机

    Jetson TX1开发笔记(一):开机设置与刷机网站:http://cuijiahua.com。 https://blog.csdn.net/c406495762/article/details/70786700 转载请注明作者和出处:http://blog.csdn.net/c406495762PC平台(Host):虚拟机Ubuntu14.04嵌入式平台(Target):JestonTX1一、开箱测试…

  • word在试图打开文件时遇到错误解决办法,亲测可用[通俗易懂]

    word在试图打开文件时遇到错误解决办法,亲测可用[通俗易懂]现象:解决办法:文件-右键属性-接除锁定如果没有接除锁定,则使用下面这个方法:“word在试图打开文件时遇到错误”解决办法,亲测可用_加鸡腿的博客-CSDN博客_windows在试图打开文件时遇到错误打开word文档时,出现以下报错:解决办法:步骤一:步骤二:步骤三:步骤四:步骤五:步骤六:步骤七:步骤八:点击【确定】即可。…https://blog.csdn.net/qq_43437571/article/details/102962500…

  • 使用GTalk服务

    使用GTalk服务Normal07.8磅02falsefalsefalseEN-USZH-CNX-NONEMicrosoftInternetExplorer4在你访问GTalk服务之前,你需要

  • PDF转换图片小工具(高清、无水印、支持随意页数)[通俗易懂]

    PDF转换图片小工具(高清、无水印、支持随意页数)[通俗易懂]疫情期间在家毕业需要,手写签名生成、成绩单的PDF文件需要加入到word中,经历了办理会员、限制5页等等的各种不方便,自己写了个小工具。平台:win764位vs15开发C#语言编写本文所编小工具,不限页数,支持高像素高清截图,随意页截取等截图如下所示:使用说明:选择起始页-终止页-像素级别(部分已默认,可以根据自己需要,一定得填写),点击按钮开始转换–选择需操作的PDF文件–选择转换完的图片的输出路径—程序提示转换成功即可。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号