首页
常用命令
About Me
推荐
weibo
github
Search
1
linuxea:gitlab-ci之docker镜像质量品质报告
48,736 阅读
2
linuxea:如何复现查看docker run参数命令
19,340 阅读
3
Graylog收集文件日志实例
17,774 阅读
4
linuxea:jenkins+pipeline+gitlab+ansible快速安装配置(1)
17,316 阅读
5
git+jenkins发布和回滚示例
17,312 阅读
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
音乐
影视
music
Internet Consulting
最后的净土
软件交付
持续集成
gitops
devops
登录
Search
标签搜索
kubernetes
docker
zabbix
Golang
mariadb
持续集成工具
白话容器
linux基础
nginx
elk
dockerfile
Gitlab-ci/cd
最后的净土
基础命令
jenkins
docker-compose
gitops
haproxy
saltstack
GitLab
marksugar
累计撰写
672
篇文章
累计收到
140
条评论
首页
栏目
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
音乐
影视
music
Internet Consulting
最后的净土
软件交付
持续集成
gitops
devops
页面
常用命令
About Me
推荐
weibo
github
搜索到
41
篇与
Golang
的结果
2020-11-09
linuxea:go有参可变函数-返回值(31)
函数对代码进行复用。这和定义一个函数类似,不同的是是对代码块起一个名字,并且可以定义一些参数,这些参数可以进行传递和接收后进行处理 ,处理的结果也需要返回。可见,函数定义有:函数名,函数体,函数参数,返回值。1.函数go没有默认值,go的函数传递是非常简单,安装参数位置进行传递。其中,参数和返回值是可以有,也可以没有的。如果代码形式就成了下面这样func 函数名(函数参数) (返回值) {}函数参数(行参),是函数快的局部变量。行参返回值都需要描述参数类型和返回值的类型。如果行参配置后,也必须传入相应的值此前,使用的 fnuc main也是函数func main(){}函数也可以赋值给变量,存储在数组,切片,映射中,也可以作为参数传递给函数或作为函数返回值进行返回。函数的参数,数量,对应类型,以及函数返回值称为函数的签名。1.1无参数无返回值函数现在,简单写一个hello world.package main import "fmt" func sayHello(){ fmt.Println("Hello world!") }而后在main函数中调用,并打印类型func main(){ fmt.Printf("%T",sayHello) sayHello() }代码块package main import "fmt" func sayHello(){ fmt.Println("Hello world!") } func main(){ fmt.Printf("%T",sayHello) sayHello() }运行[root@LinuxEA /opt/Golang/work3]# go run func.go func()Hello world! Hello world!在main函数中可以调用多次sayHello函数package main import "fmt" func sayHello(){ fmt.Println("Hello world!") } func main(){ fmt.Printf("%T",sayHello) sayHello() sayHello() sayHello() sayHello() sayHello() }运行[root@LinuxEA /opt/Golang/work3]# go run func.go func()Hello world! Hello world! Hello world! Hello world! Hello world! Hello world!1.2有参数无返回值函数如上,在sayHello中加上参数name string。这里的参数也可以称为行参如果设置了多少个行参,也必须传入多个。func sayHello(name string){ fmt.Printf("Hello %s!",name) }name string是字符串类型,调用的时候也需要传入字符串.这里传入的是"mark"给sayHello,打印的时候打印的name就是mark。main函数中传递的参数也可以称为实参func main(){ sayHello("mark") }代码块[root@LinuxEA /opt/Golang/work3]# cat func2.go package main import "fmt" func sayHello(name string){ fmt.Printf("Hello %s!",name) } func main(){ sayHello("mark") }运行[root@LinuxEA /opt/Golang/work3]# go run func2.go Hello mark!或者也可以赋值传递 name := "sean" sayHello(name)代码块[root@LinuxEA /opt/Golang/work3]# cat func2.go package main import "fmt" func sayHello(name string){ fmt.Printf("Hello %s!",name) } func main(){ sayHello("mark") fmt.Println("\n") name := "sean" sayHello(name) }运行[root@LinuxEA /opt/Golang/work3]# go run func2.go Hello mark! Hello sean!1.3有返回值有参数函数写一个计算加法的函数,如下func add(a,b int)int{ return a + b }有俩个参数,分别是a和b,都是int类型,返回值也是Int类型。直接return行参即可在main函数中给add传入两个实参。并且需要一个值来接收。比如a。并且打印func main(){ a := add(1,2) fmt.Println(a) }也可以直接打印fmt.Println(add(1,2))代码块package main import "fmt" func add(a,b int)int{ return a + b } func main(){ a := add(1,2) fmt.Println(a) }运行[root@LinuxEA /opt/Golang/work3]# go run add.go 31.4可变参数可变参数也需要定义名称,参数类型使用...。三个点可变参数只能定义一个,并且一般只能定义在末尾定义a和b,而后定义可变参数args,可以有,也可以没有,使用三个点表示,而后写上类型,这里使用的是int,最后打印并返回一个0 .如下:并且打印出args类型:func addN(a,b int,args ...int) int { fmt.Println(a,b,args) fmt.Printf("%T",args) return 0 }在main中调用的时候,可以传入args,也可以不传func main(){ fmt.Println(addN(1,2)) fmt.Println(addN(1,2,3,4,5,6)) }运行[root@LinuxEA /opt/Golang/work3]# go run addn.go 1 2 [] []int0 1 2 [3 4 5 6] []int0可以看到,args的类型是一个切片。1.5计算可变参数值如上,现在将可变参数中的值进行相加,可变元素和a,b相加,args是切片。那么,现在通过遍历进行相加。首先,将a,b相加 titak := a + b而后遍历args切片,进行相加 for _,v := range args { titak += v }最后返回 return titak代码块[root@LinuxEA /opt/Golang/work3]# cat addn.go package main import "fmt" func addN(a,b int,args ...int) int { titak := a + b for _,v := range args { titak += v } return titak } func main(){ fmt.Println(addN(1,2)) fmt.Println(addN(1,2,3,4,5,6)) }运行[root@LinuxEA /opt/Golang/work3]# go run addn.go 3 211.6args函数中传递接上述的函数。现在创建一个cacl的函数,将addN的args传递进来。args默认是一个空切片,这时候就可以使用args的解包操作args...。解包的作用是将args从传递中进行解包(在本节案例中,解包后就是int类型),所以这里是有三个点,否则就变成了传递args元素。...操作只能在切片上如下:func cacl(op string,a,b int,args ...int) int { switch op { case "add": return addN(a,b,args...) } return -1 }而后在main函数中传递op字符串参数,a,b的int类型,args是可选参数。cacl("add",1,2):传递给cacl,第一个参数add,第二个1,1对于a,第二个2,2对应2。第三个参数没有,args为空切片。调用addN函数相加cacl("add",1,2,5):传递给cacl,第一个参数add,第二个1,1对于a,第二个2,2对应2。第三个参数是5,args解包切片中是5。调用addN函数相加cacl("add",1,2,5,8):传递给cacl,第一个参数add,第二个1,1对于a,第二个2,2对应2。第三个参数是5,args解包切片中是5。第四个参数是8,args解包切片中是8。调用addN函数相加如下:func main(){ fmt.Println(cacl("add",1,2)) fmt.Println(cacl("add",1,2,5)) fmt.Println(cacl("add",1,2,5,8)) }代码块[root@LinuxEA /opt/Golang/work3]# cat addn2.go package main import "fmt" func addN(a,b int,args ...int) int { titak := a + b for _,v := range args { titak += v } return titak } func cacl(op string,a,b int,args ...int) int { switch op { case "add": return addN(a,b,args...) } return -1 } func main(){ fmt.Println(cacl("add",1,2)) fmt.Println(cacl("add",1,2,5)) fmt.Println(cacl("add",1,2,5,8)) }运行[root@LinuxEA /opt/Golang/work3]# go run addn2.go 3 8 16除了以上的方式,在main函数中还可以修改,通过args的方式传入func main(){ args := []int{1,2,3,4,56,67} fmt.Println(addN(1,2,args...)) fmt.Println(cacl("add",1,2,args...)) }运行[root@LinuxEA /opt/Golang/work3]# go run addn2.go 136 1361.7解包删除切片如下:nums := []int{1,2,5,8,0}删除中间的5和之前的copy删除类型,用nums[:2],拿出索引start-2,在用nums[3:],拿出索引3到END。将nums[:2],nums[3:]...打印 fmt.Println("nums[:2]:",nums[:2]) fmt.Println("nums[3:]:",nums[3:])拿到的结果是[root@LinuxEA /opt/Golang/work3]# go run del.go nums[:2]: [1 2] nums[3:]: [8 0]加在一起就是1,2,8,0,而后使用append添加到nums中。这里必须用到nums[3:]...的解包。这是核心nums = append(nums[:2],nums[3:]...)代码块package main import "fmt" func main(){ nums := []int{1,2,5,8,0} nums = append(nums[:2],nums[3:]...) fmt.Println(nums) }运行[root@LinuxEA /opt/Golang/work3]# go run del.go [1 2 8 0]1.8返回值go中,函数所有的分支必须有返回值。在一个函数的逻辑中需要。在上述代码中return了-1,这里返回-1是因为返回值是int类型。如下:func cacl(op string,a,b int,args ...int) int { switch op { case "add": return addN(a,b,args...) } return -1 }return -1,-1在这里是说(只要是int类型就可以 ),不管有没有返回的结果,这里都会返回-1。因为在函数逻辑中这里是有返回值的。这似乎并不明了,写个简单的示例.执行两次 return 1 return 0并进行标注,看会发生什么package main import "fmt" func testReturn() int { fmt.Println("return 1 前") return 1 fmt.Println("return 1 后") return 0 } func main(){ fmt.Println(testReturn()) }运行[root@LinuxEA /opt/Golang/work3]# go run return.go return 1 前 1这里看到只是执行了return 1,这是因为代码执行到return后就不会在执行后面的了。而上述定义的return 2在执行了return 1后是永远都不会执行的。而在go中支持多个返回值。多返回值示例:cacl函数,有a和b两个行参,满足加减乘除。在go中,支持多个返回值,于是,代码就可以写成这样return a+b,a-b,a*b,a/b而return了四个返回值后,也需要4个类型来接收func calc(a,b int) (int,int,int,int) { return a+b,a-b,a*b,a/b }代码块package main import "fmt" func calc(a,b int) (int,int,int,int) { return a+b,a-b,a*b,a/b } func main(){ fmt.Println(calc(9,3)) }运行计算,a是9,b是3的加减乘除计算结果[root@LinuxEA /opt/Golang/work3]# go run calc.go 12 6 27 3当然,在main函数中,这里也可以分开传递,并且可以进行单个屏蔽,比如屏蔽a4,也就是除法,使用下划线即可。func main(){ a1,a2,a3,_ := calc(9,3) fmt.Println(a1,a2,a3) }运行[root@LinuxEA /opt/Golang/work3]# go run calc.go 12 6 27命名返回值上述的返回值是没有定义名称的,我们也可以定一个名称,定义名称后就可以直接return 返回值变量的最终结果返回。还是以加减乘除,如下:func calc2(a,b int) (sum int,diff int,product int,merchant int) { sum = a + b diff = a - b product = a * b merchant = a / b return }func main(){ fmt.Println(calc2(10,2)) }运行[root@LinuxEA /opt/Golang/work3]# go run calc2.go 12 8 20 5如果没有任何赋值就会返回0。命名返回值在代码量较多的时候查看和使用较为不便。1.9递归递归是指函数直接或间接调用自己,递归常用于解决分治问题,为相同的小问题进行解决,需要关注终止条件。计算0到100的和,用n的阶乘:f(n) 1...n0 - 100的和,等于0-99的和加上100,用函数表示就是f(99)+1000 - 99的和,等于0-98的和加上99,用函数表示就是f(98)+99函数就成了f(n) = n + f(n-1),而f(1) = 1的时候使用递归实现仍然计算一个1到100的和,假设是Addn的函数,返回值也是int.return的结果就是n + Addn(n-1)func Addn(n int) int{ return n + Addn(n-1) }计算0-5的和.func main(){ fmt.Println(Addn(5)) }这样就相当于从5开始计算Addn(5) => 5 + Addn(4) Addn(4) => 4 + Addn(3) Addn(3) => 3 + Addn(2) Addn(2) => 2 + Addn(1) Addn(1) = 1 + Addn(0)终止条件这样就会一直执行,递归会一直调用自己,形成了死循环。需要一个结束条件语句。当n等于1的时候就返回 if n == 1 { return 1 }如下:func Addn(n int) int{ if n == 1 { return 1 } return n + Addn(n-1) }这样代码执行完成package main import "fmt" func Addn(n int) int{ if n == 1 { return 1 } fmt.Println("计算f(n):",n) return n + Addn(n-1) } func main(){ fmt.Println(Addn(5)) }运行[root@LinuxEA /opt/Golang/work3]# go run add2.go 计算f(n): 5 计算f(n): 4 计算f(n): 3 计算f(n): 2 15
2020年11月09日
2,149 阅读
0 评论
0 点赞
2020-04-20
linuxea:go其他类型转换字符串(30)
Sprintf可以将其他类型转换成字符串1.1将int转换字符串Sprintf转换int到字符串,%dfmt.Sprintf("%d",12)代码块package main import ( "fmt" ) func main(){ a := fmt.Sprintf("%d",12) fmt.Println(a) fmt.Printf("%T",a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt.go 12 string1.2float浮点数转换为字符串Sprintf转换float到字符串,%ffmt.Sprintf("%f",12.2)代码块package main import ( "fmt" ) func main(){ a := fmt.Sprintf("%f",12.2) fmt.Println(a) fmt.Printf("%T",a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt2.go 12.200000 string1.3FormatBool布尔转换字符串将bool转换字符串strconv.FormatBool(false)代码块package main import ( "fmt" "strconv" ) func main(){ a := strconv.FormatBool(false) fmt.Printf("%T,%v",a,a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt3.go string,false1.4 Itoa将int类型转换为字符串将int类型转换为字符串 strconv.Itoa(123)代码块package main import ( "fmt" "strconv" ) func main(){ a := strconv.Itoa(123) fmt.Printf("%T,%v",a,a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt4.go string,1231.5 FormatInt进制类型转换字符串123转换10进制strconv.FormatInt(123,10)代码块package main import ( "fmt" "strconv" ) func main(){ a := strconv.FormatInt(123,10) fmt.Printf("%T,%v",a,a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt5.go string,123123转换16进制package main import ( "fmt" "strconv" ) func main(){ a := strconv.FormatInt(123,16) fmt.Printf("%T,%v",a,a) }[root@www.linuxea.com /opt/Golang/work2]# go run fmt5.go string,7b123转换8进制package main import ( "fmt" "strconv" ) func main(){ a := strconv.FormatInt(123,8) fmt.Printf("%T,%v",a,a) }[root@www.linuxea.com /opt/Golang/work2]# go run fmt5.go string,1731.6 FormatFloat转换字符串指定一个十进制或者科学记数法,‘E’是科学计数法,如果是转换10进制这里写'f',-1精度,64是float64类型strconv.FormatFloat(10.11,'E',-1,64)代码块package main import ( "fmt" "strconv" ) func main(){ a := strconv.FormatFloat(10.11,'E',-1,64) fmt.Printf("%T,%v",a,a) }运行[root@www.linuxea.com /opt/Golang/work2]# go run fmt5.go string,1.011E+01
2020年04月20日
3,291 阅读
0 评论
0 点赞
2020-04-16
linuxea:go字符串与其他类型的转换(29)
1.字符串与其他类型的转换转换bool,int1.1字符串转换Bool类型如下:strconv.ParseBool("true")会返回两个值,其中一个是err,接收两个值,如果err等于nil,说明没有错误,就打印v,如果有错误,就打印。如下:[root@www.linuxea.com /opt/Golang/work2]# cat strcov.go package main import ( "fmt" "strconv" ) func main(){ if v,err := strconv.ParseBool("true");err == nil { fmt.Println(v) } else { fmt.Println(err) } } 运行[root@www.linuxea.com /opt/Golang/work2]# go run strcov.go true1.2字符串转换int类型如下:strconv.Atoi("1024")会返回两个值,其中一个是err,接收两个值,如果err等于nil,说明没有错误,就打印v,如果有错误,就打印。如下:[root@www.linuxea.com /opt/Golang/work2]# cat strcov.go package main import ( "fmt" "strconv" ) func main(){ if v,err := strconv.Atoi("1024");err == nil{ fmt.Println(v) }else{ fmt.Println(err) } }运行[root@www.linuxea.com /opt/Golang/work2]# go run atoi.go 1024另外,使用strconv.ParseInt()也可以转换成int类型,但是需要指定转换的字节 if v,err := strconv.ParseInt("64",16,64);err == nil { fmt.Println(v) }else{ fmt.Println(err) }[root@www.linuxea.com /opt/Golang/work2]# go run atoi.go 10016*6+4=1001.3字符串转换float如下:strconv.ParseFloat("1.024",64)会返回两个值,其中一个是err,接收两个值,如果err等于nil,说明没有错误,就打印v,如果有错误,就打印。如下:package main import ( "fmt" "strconv" ) func main(){ if v,err := strconv.ParseFloat("1.024",64);err == nil{ fmt.Println(v) fmt.Printf("%T",v) }else{ fmt.Println(err) } }
2020年04月16日
2,466 阅读
0 评论
0 点赞
2020-02-04
linuxea:go字符串和字节(28)
8.字符串和字节字符串和字节切片区别bytes: 将buffer对象转换为字节切片String: 将buffer对象转化为字符串转换可以将string通过函数byte[]转化为字节切片,同时也可通过8.1strings包介绍strings包提供操作UFT-8字符串常用函数a).常用函数Compare: 比较字符串Contains:是否包含子字符串Count: 字符串出现次数EqualFold: 不区分大小写比较Fields: 按空白符分割字符串Split: 分割字符串为切片Join: 将字符串切片链接LastIndex: 获取字符串最后一次出现的位置Hasprefix: 是否以字符串作为某个字符串开头HasSuffix: 是否以字符串作为某个字符串结尾Index: 获取字符串首次出现等8.2strings常用操作比较字符串package main import ( "fmt" "strings" ) func main(){ fmt.Println(strings.Compare("abc","bac")) }不相等则是-1,否则是0[root@www.linuxea.com /opt/Golang/work2]# go run string.go -1是否包含某字符串abc是否包含bc,包含则为truefmt.Println(strings.Contains("abc","bc"))运行[root@www.linuxea.com /opt/Golang/work2]# go run string.go true只要包含一个字符就为tureabcdsadasdasdas只要包含一个b就为truefmt.Println(strings.Contains("abcdsadasdasdas","b"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go true获取字符串出现的次数获取abcdsadasdasdas中a出现的次数fmt.Println(strings.Count("abcdsadasdasdas","a"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go 5分割按空白字符分割 fmt.Println(strings.Fields("abc def\n eeee")) fmt.Printf("%q\n",strings.Fields("abc def\n eeee"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go [abc def eeee] ["abc" "def" "eeee"]以什么结尾和开头HasPrefix是以什么开头,如果是就为trueHasSuffix是以什么结尾,如果是就为true fmt.Println(strings.HasPrefix("abcd","ab")) fmt.Println(strings.HasSuffix("abcd","cd"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go true true索引位置cd在abcd中的索引位置,如果存在则打印索引位置,如果不存在就等于-1fmt.Println(strings.Index("abcd","cd"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go 2这里还有Lastindex,就是最后出现的索引位置 fmt.Println(strings.LastIndex("abcdaasxcd","cd"))[root@www.linuxea.com /opt/Golang/work2]# go run string.go 8分隔符fmt.Println(strings.Split("adbcdef;abcd;abcd3edsa",";"))以;进行分割[root@www.linuxea.com /opt/Golang/work2]# go run string.go [adbcdef abcd abcd3edsa]连接符fmt.Println(strings.Join([]string{"adb","abcd","abcd3edsa"},"~"))以~进行链接[root@www.linuxea.com /opt/Golang/work2]# go run string.go adb~abcd~abcd3edsa重复N份fmt.Println(strings.Repeat("abc",3))将acb重复三次[root@www.linuxea.com /opt/Golang/work2]# go run string.go abcabcabc替换将abcabcabcabc中的a替换成1,1表示替换一次 fmt.Println(strings.Replace("abcabcabcabc","a","1",1))将abcabcabcabc中的a替换成1,-1表示全部替换 fmt.Println(strings.Replace("abcabcabcabc","a","1",-1))将abcabcabcabc中的a替换成1,ReplaceAll不需要指定替换多少次,默认替换全部 fmt.Println(strings.ReplaceAll("abcabcabcabc","a","1"))运行[root@www.linuxea.com /opt/Golang/work2]# go run string.go 1bcabcabcabc 1bc1bc1bc1bc 1bc1bc1bc1bc大小写转换ToLower转换小写,ToUpper转换大写 fmt.Println(strings.ToLower("abcABC")) fmt.Println(strings.ToUpper("abcABC"))运行[root@www.linuxea.com /opt/Golang/work2]# go run string.go abcabc ABCABC首字母大写fmt.Println(strings.Title("hello"))将hello首字母大写[root@www.linuxea.com /opt/Golang/work2]# go run string.go Hello前后字符去掉fmt.Println(strings.Trim("xhelloxz","xz"))去掉xhelloxz前后包括xz或者前后包含x,z的字符[root@www.linuxea.com /opt/Golang/work2]# go run string.go hello去除空白字符fmt.Println(strings.TrimSpace(" hello \n \r "))[root@www.linuxea.com /opt/Golang/work2]# go run string.go hello8.3定义字节切片byte是无符号的uint8类型。package main import ( "fmt" ) func main(){ var bytes []byte = []byte{'a','b','c'} fmt.Printf("%T,%#v\n",bytes,bytes) }[root@www.linuxea.com /opt/Golang/work2]# go run byte.go []uint8,[]byte{0x61, 0x62, 0x63}这里a,b,c的ASCII分别是0x61, 0x62, 0x638.4字节转换字符串直接使用string转换即可package main import ( "fmt" ) func main(){ var bytes []byte = []byte{'a','b','c'} fmt.Printf("%T,%#v\n",bytes,bytes) sb := string(bytes) fmt.Printf("%T %v\n",sb,sb) }将定义的bytes转换成字符串[root@www.linuxea.com /opt/Golang/work2]# go run byte.go []uint8,[]byte{0x61, 0x62, 0x63} string abc8.5字符串转字节将转换过的字符串再转回字节package main import ( "fmt" ) func main(){ var bytes []byte = []byte{'a','b','c'} fmt.Printf("%T,%#v\n",bytes,bytes) sb := string(bytes) fmt.Printf("%T %v\n",sb,sb) bs := []byte(sb) fmt.Printf("%T %#v\n",bs,bs) }如下[root@www.linuxea.com /opt/Golang/work2]# go run byte.go []uint8,[]byte{0x61, 0x62, 0x63} string abc []uint8 []byte{0x61, 0x62, 0x63}8.6bytes包bytes包与strings包基本上一样Compare 比较按照直接数组进行比较fmt.Println(bytes.Compare([]byte("abc"),[]byte("def")))运行[root@www.linuxea.com /opt/Golang/work2]# go run byte.go -1Index索引位置bytes.Index索引位置计算字节def在abcdef的索引位置fmt.Println(bytes.Index([]byte("abcdef"),[]byte("def")))运行[root@www.linuxea.com /opt/Golang/work2]# go run byte.go 3bytes.Contains字节abcdef是否包含def,如果包含则为true,否则falsefmt.Println(bytes.Contains([]byte("abcdef"),[]byte("def")))运行[root@www.linuxea.com /opt/Golang/work2]# go run byte.go true8.7计算unicode当使用len计算字符串是可以的,但是遇到中文字符就需要unicode/utf8模块计算。如下:[root@www.linuxea.com /opt/Golang/work2]# cat byte1.go package main import ( "fmt" "unicode/utf8" ) func main(){ s := "这是一个测试" fmt.Println(s) fmt.Println(utf8.RuneCountInString(s)) }运行[root@www.linuxea.com /opt/Golang/work2]# go run byte1.go 这是一个测试 6
2020年02月04日
2,185 阅读
1 评论
0 点赞
2020-01-17
linuxea:go映射的定义和增删改(27)
key和value通过某一种关系,在访问的时候通过key访问value,而映射存储的就是key,value结构(映射是存储一系列无序的key/value对),通过key对value进行查询。key/value规则映射的key只能为可使用==运算符的值类型(字符串,数字,布尔,数组),因为key至少要进行判断,value可以为任何类型7.1定义一个映射使用map定义,可以定义key是运算符的值任何value类型,如:[]括号内是key的类型,值是int类型的映射,如下:var scores map[string]int[root@www.linuxea.com_1 /opt/Golang/work2]# cat map.go package main import "fmt" func main(){ var scores map[string]int fmt.Printf("%T %v\n",scores,scores) fmt.Println(scores == nil) }打印[root@www.linuxea.com_1 /opt/Golang/work2]go run map.go map[string]int map[] true如果映射会nil,是不能进行操作的7.2映射字面量可以直接使用map定义scores = map[string]int{}{}空,就没有值。假如输入"mark":2,"marksugar":3,进行初始化 scores = map[string]int{"mark":2,"marksugar":3} fmt.Println(scores)运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go map[mark:2 marksugar:3]也可以使用make,如:make(map[string]int{}),也是空值。和scores = map[string]int{}一样7.3映射的增删改查查查找mark的,使用scores["mark"]即可fmt.Println(scores["mark"])运行得到的value是2[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go 2在映射中如果访问一个不存在的key结果将会返回对应value的0值。在key访问的时候,可以通过返回值来进行判断存在与否。如下: _,ok := scores["sean"] if ok{ fmt.Println(scores["sean"]) }else{ fmt.Println("不存在") }这种写法的简写如下 if _,ok := scores["sean"];ok{ fmt.Println(scores["sean"]) }else{ fmt.Println("不存在") }如果为true则说明存在,如果是false说明不存在。运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go 不存在修改直接重新赋值,此刻修改mark的value等于10:scores["mark"] = 10 fmt.Println("mark:",scores["mark"]) scores["mark"] = 10 fmt.Println("mark:",scores["mark"])[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go mark: 2 mark: 10如果赋值一个不存在的key的值将会添加。如果存在则是修改。删除假如此时删除mark,直接使用delete(scores,"mark")即可 fmt.Println(scores) delete(scores,"mark") fmt.Println(scores)运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go map[mark:10 marksugar:3] map[marksugar:3]添加在将mark添加 回来:scores["mark"] = 66 scores["mark"] = 66 fmt.Println(scores)运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go map[mark:66 marksugar:3]增删改查代码块package main import "fmt" func main(){ var scores map[string]int fmt.Printf("%T %v\n",scores,scores) fmt.Println(scores == nil) scores = map[string]int{"mark":2,"marksugar":3} fmt.Println(scores) fmt.Println(scores["mark"]) if _,ok := scores["sean"];ok{ fmt.Println(scores["sean"]) }else{ fmt.Println("不存在") } if _,ok := scores["marksugar"];ok{ fmt.Println(scores["marksugar"]) }else{ fmt.Println("不存在") } fmt.Println("mark:",scores["mark"]) scores["mark"] = 10 fmt.Println("mark:",scores["mark"]) fmt.Println(scores) delete(scores,"mark") fmt.Println(scores) scores["mark"] = 66 fmt.Println(scores) }7.4映射的长度获取使用len即可,如:len(scores)7.5遍历映射直接可以使用for rage进行遍历,但是遍历结果顺序和添加的顺序是没有关系的。因为映射是无序的,这和映射hash有关。如遍历scores for k,v := range scores{ fmt.Println(k,v) }结果root@www.linuxea.com_1 /opt/Golang/work2]# go run map.go mark 66 marksugar 37.6定义映射的映射如果现在要定义一个映射,格式是: 映射[字符串]字符串{"地址","电话",”身高“}。那么格式如下:var users map[string]map[string]string在进行初始化users = map[string]map[string]string{"mark":{"地址":"上海","电话":"10086","身高":"一米八"}}打印fmt.Printf("%T,%v\n",users,users)如下:\#go run map2.go map[string]map[string]string,map[mark:map[地址:上海 电话:10086 身高:一米八]]增删改查添加一个sean users["sean"] = map[string]string{"地址":"上海","电话":"10086","身高":"一米八"} fmt.Printf("%T,%v\n",users,users)而后修改mark的地址和身高 users["mark"] = map[string]string{"地址":"上海","电话":"10086","身高":"1.9"} users["mark"]["地址"] = "北京" fmt.Printf("%T,%v\n",users,users)而后在删除mark字段的电话 delete(users["mark"],"电话") fmt.Printf("%T,%v\n",users,users)代码块package main import "fmt" func main(){ var users map[string]map[string]string users = map[string]map[string]string{"mark":{"地址":"上海","电话":"10086","身高":"一米八"}} fmt.Printf("%T,%v\n",users,users) users["sean"] = map[string]string{"地址":"上海","电话":"10086","身高":"一米八"} fmt.Printf("%T,%v\n",users,users) users["mark"] = map[string]string{"地址":"上海","电话":"10086","身高":"1.9"} users["mark"]["地址"] = "北京" fmt.Printf("%T,%v\n",users,users) delete(users["mark"],"电话") fmt.Printf("%T,%v\n",users,users) }运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run map2.go map[string]map[string]string,map[mark:map[地址:上海 电话:10086 身高:一米八]] map[string]map[string]string,map[mark:map[地址:上海 电话:10086 身高:一米八] sean:map[地址:上海 电话:10086 身高:一米八]] map[string]map[string]string,map[mark:map[地址:北京 电话:10086 身高:1.9] sean:map[地址:上海 电话:10086 身高:一米八]] map[string]map[string]string,map[mark:map[地址:北京 身高:1.9] sean:map[地址:上海 电话:10086 身高:一米八]]7.7练习题1统计映射内字段出现的次数1.统计以下字符串出现的次数users := []string{"mark","sean","mark","edwin","mark","justin"}示例:首先,key是string,value是int的映射user_stat := make(map[string]int)而后使用for range遍历users,使用if判断遍历的结果,如果为true,也就是存在就就加1,否则赋值等于1,添加到user_stat映射中 for _,user := range users { if _,ok := user_stat[user];ok{ user_stat[user]++ }else { user_stat[user] =1 } }而后打印user_statfmt.Println(user_stat)代码块[root@www.linuxea.com_1 /opt/Golang/work2]# cat work1.go package main import "fmt" func main(){ users := []string{"mark","sean","mark","edwin","mark","justin"} user_stat := make(map[string]int) for _,user := range users { if _,ok := user_stat[user];ok{ user_stat[user]++ }else { user_stat[user] =1 } } fmt.Println(user_stat) }运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run work1.go map[edwin:1 justin:1 mark:3 sean:1]这段代码可以进行简化。在go的映射中如果值不存在返回是0,那就可以直接进行++。逻辑就成了,如果遍历一次就加一次。如果值不存在就成了1+0,如果存在就会继续相加[root@www.linuxea.com_1 /opt/Golang/work2]# cat work1.go package main import "fmt" func main(){ users := []string{"mark","sean","mark","edwin","mark","justin"} user_stat := make(map[string]int) for _,user := range users { user_stat[user]++ } fmt.Println(user_stat) }运行[root@www.linuxea.com /opt/Golang/work2]# go run work2.go map[edwin:1 justin:1 mark:3 sean:1]7.8练习题2统计文章内字母出现的次数示例:我从github找了一段,声明articlearticle := `Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additionsto that Work or Derivative Works thereof, that is intentionallysubmitted to Licensor for inclusion in the Work by the copyright owneror by an individual or Legal Entity authorized to submit on behalf ofthe copyright owner. For the purposes of this definition, "submitted"means any form of electronic, verbal, or written communication sentto the Licensor or its representatives, including but not limited tocommunication on electronic mailing lists, source code control systems,and issue tracking systems that are managed by, or on behalf of, theLicensor for the purpose of discussing and improving the Work, butexcluding communication that is conspicuously marked or otherwisedesignated in writing by the copyright owner as "Not a Contribution.""Contributor" shall mean Licensor and any individual or Legal Entityon behalf of whom a Contribution has been received by Licensor andsubsequently incorporated within the Work.2. Grant of Copyright License. Subject to the terms and conditions ofthis License, each Contributor hereby grants to You a perpetual,worldwide, non-exclusive, no-charge, royalty-free, irrevocablecopyright license to reproduce, prepare Derivative Works of,publicly display, publicly perform, sublicense, and distribute theWork and such Derivative Works in Source or Object form.Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,worldwide, non-exclusive, no-charge, royalty-free, irrevocable(except as stated in this section) patent license to make, have made,use, offer to sell, sell, import, and otherwise transfer the Work,where such license applies only to those patent claims licensableby such Contributor that are necessarily infringed by theirContribution(s) alone or by combination of their Contribution(s)with the Work to which such Contribution(s) was submitted. If Youinstitute patent litigation against any entity (including across-claim or counterclaim in a lawsuit) alleging that the Workor a Contribution incorporated within the Work constitutes director contributory patent infringement, then any patent licensesgranted to You under this License for that Work shall terminateas of the date such litigation is filed.`而后定义一个映射key是rune,value是intarticle_stat := map[rune]int{}而后遍历article,遍历的value,如果值小于等于A,大于等于Z。并且大于等于a,小于等于z,就将值加1。代码块如下: for _,ch := range article { if ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' { article_stat[ch]++ } }运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run work3.go map[67:12 68:3 69:2 70:1 71:2 73:1 76:12 78:1 79:1 80:1 83:3 87:14 89:4 97:117 98:45 99:81 100:53 101:193 102:36 103:31 104:73 105:178 106:3 107:18 108:69 109:36 110:160 111:177 112:35 113:1 114:142 115:111 116:197 117:66 118:18 119:20 120:4 121:39 122:1]为了更方便查看,遍历article_stat,打印出key和value for ch,cnt := range article_stat { fmt.Printf("%c:%d\n",ch,cnt) }完整的代码块[root@www.linuxea.com_1 /opt/Golang/work2]# cat work3.go package main import "fmt" func main(){ article := `Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additionsto that Work or Derivative Works thereof, that is intentionallysubmitted to Licensor for inclusion in the Work by the copyright owneror by an individual or Legal Entity authorized to submit on behalf ofthe copyright owner. For the purposes of this definition, "submitted"means any form of electronic, verbal, or written communication sentto the Licensor or its representatives, including but not limited tocommunication on electronic mailing lists, source code control systems,and issue tracking systems that are managed by, or on behalf of, theLicensor for the purpose of discussing and improving the Work, butexcluding communication that is conspicuously marked or otherwisedesignated in writing by the copyright owner as "Not a Contribution.""Contributor" shall mean Licensor and any individual or Legal Entityon behalf of whom a Contribution has been received by Licensor andsubsequently incorporated within the Work.2. Grant of Copyright License. Subject to the terms and conditions ofthis License, each Contributor hereby grants to You a perpetual,worldwide, non-exclusive, no-charge, royalty-free, irrevocablecopyright license to reproduce, prepare Derivative Works of,publicly display, publicly perform, sublicense, and distribute theWork and such Derivative Works in Source or Object form.Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,worldwide, non-exclusive, no-charge, royalty-free, irrevocable(except as stated in this section) patent license to make, have made,use, offer to sell, sell, import, and otherwise transfer the Work,where such license applies only to those patent claims licensableby such Contributor that are necessarily infringed by theirContribution(s) alone or by combination of their Contribution(s)with the Work to which such Contribution(s) was submitted. If Youinstitute patent litigation against any entity (including across-claim or counterclaim in a lawsuit) alleging that the Workor a Contribution incorporated within the Work constitutes director contributory patent infringement, then any patent licensesgranted to You under this License for that Work shall terminateas of the date such litigation is filed.` article_stat := map[rune]int{} for _,ch := range article { if ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' { article_stat[ch]++ } } fmt.Println(article_stat) for ch,cnt := range article_stat { fmt.Printf("%c:%d\n",ch,cnt) } }运行[root@www.linuxea.com_1 /opt/Golang/work2]# go run work3.go map[67:12 68:3 69:2 70:1 71:2 73:1 76:12 78:1 79:1 80:1 83:3 87:14 89:4 97:117 98:45 99:81 100:53 101:193 102:36 103:31 104:73 105:178 106:3 107:18 108:69 109:36 110:160 111:177 112:35 113:1 114:142 115:111 116:197 117:66 118:18 119:20 120:4 121:39 122:1] E:2 F:1 d:53 v:18 W:14 L:12 C:12 i:178 c:81 G:2 I:1 o:177 r:142 m:36 z:1 x:4 w:20 k:18 N:1 j:3 s:111 h:73 y:39 n:160 p:35 S:3 D:3 q:1 Y:4 P:1 u:66 a:117 e:193 f:36 g:31 O:1 t:197 b:45 l:69
2020年01月17日
2,241 阅读
0 评论
0 点赞
2020-01-10
linuxea:go多维切片和切片与数组的区别(26)
二维切片1多维切片定义使用两个括号定义二维切片[][]int{}points := [][]int{}2多维切片赋值points = append(points,[]int{1,2,3}) points = append(points,[]int{4,5,6})fmt.Println(points)而后打印结果[root@linuxea.com /opt/Golang/work2]# go run dmake.go [[1 2 3] [4 5 6]]3 多维查询仍然使用索引进行查询。对于多维切片来讲,获取其中某一维就需要多次索引。如果要获取2,就需要在1维索引0位置的切片points[0],而后通过索引1位置points[0][2]找到 fmt.Println(points) fmt.Println(points[0]) fmt.Println(points[0][3])运行[root@linuxea.com /opt/Golang/work2]# go run dmake.go [[1 2 3] [4 5 6]] [1 2 3] 2切片与数组的区别切片定义一个切片。如下:slice01 := []int{1,2,3}而后,赋值给slice02slice02 := slice01而后在修改slice02索引0位置的元素,并打印slice02[0] = 99 fmt.Printf("slice01:%v,slice02:%v\n",slice01,slice02)在修改slice01索引0位置的元素,并打印 slice01[0] = 1 fmt.Printf("slice01:%v,slice02:%v\n",slice01,slice02)代码块如下:package main import "fmt" func main(){ slice01 := []int{1,2,3} slice02 := slice01 fmt.Printf("slice01:%v,slice02:%v\n",slice01,slice02) slice02[0] = 99 fmt.Printf("slice01:%v,slice02:%v\n",slice01,slice02) slice01[0] = 1 fmt.Printf("slice01:%v,slice02:%v\n",slice01,slice02) } 运行[root@linuxea.com /opt/Golang/work2]# go run dmake2.go slice01:[1 2 3],slice02:[1 2 3] slice01:[99 2 3],slice02:[99 2 3] slice01:[1 2 3],slice02:[1 2 3]当修改了slice01的时候,slice02也会随着改变,当修改slice02的时候,slice01也会随着改变。数组数组是长度固定的,在go中,数组是不可变的,是值类型。用切片同样的定义和修改数组看会发生什么?package main import "fmt" func main(){ array01 := [3]int{1,2,3} array02 := array01 fmt.Printf("array01:%v,array02:%v\n",array01,array02) array02[0] = 99 fmt.Printf("array01:%v,array02:%v\n",array01,array02) array01[0] = 1 fmt.Printf("array01:%v,array02:%v\n",array01,array02) }运行[root@linuxea.com /opt/Golang/work2]# go run dmake3.go array01:[1 2 3],array02:[1 2 3] array01:[1 2 3],array02:[99 2 3] array01:[1 2 3],array02:[99 2 3]此时的array01修改不会影响到array02,array02也不会影响到array01。这是为什么?切片的底层有三个元素,point(指针),len,cap。有一个底层数组,假设这个数组地址是0XZ2S63Q,point就指向0XZ2S63Q。而将slice01赋值给slice02(slice02 := slice01)的时候,是值传递。slice01就相当于被拷在go中赋值是值传递,相当于一次COPY贝到slice02,但是地址仍然指向slice01的0XZ2S63Q。如下图这也就是为什么对slice01修改会作用于slice02,slice02修改也会作用于slice01。而当数组在赋值的时候,会在内存中重新申请一个同样大小底层数组,并将值COPY到赋值的函数上。如下:这也就是为什么数组重新赋值后,修改互相不影响。
2020年01月10日
2,182 阅读
0 评论
0 点赞
2019-12-29
linuxea:go切片复制和删除与应用(25)
4.9.1切片的复制和删除copy我们定义两个函数,分别不同长度的元素 nums01 := []int{1,2,3} nums02 := []int{10,20,30,40,50}切片的复制使用copy。我们将nums01复制到nums02.在copy中,目标在后。复制的源在前copy(nums02,nums01)而后打印nums02fmt.Println(nums02)运行[root@www.linuxea.com /opt/Golang/work2]# go run make7.go [1 2 3 40 50]nums01的三个元素复制到nums02,而nums02的后两个元素没有变。nums2长,而nums01短,假如此时nums02复制到nums01会怎么样。如下:package main import "fmt" func main(){ nums01 := []int{1,2,3} nums02 := []int{10,20,30,40,50} copy(nums01,nums02) fmt.Println(nums01) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make7.go [10 20 30]得到的结果是10,20,30。这是因为nums01只有三个元素,nums02复制到nums01也只复制了三个。这也就完成了删除操作。nums02删除掉了40和50的元素。copy删除删除第一个元素和最后一个元素。我们使用切片操作。开始删除第一个nums06[1:][root@www.linuxea.com /opt/Golang/work2]# cat make8.go package main import "fmt" func main(){ nums06 := []int{1,2,3,4,5} fmt.Println(nums06[1:]) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make8.go [2 3 4 5]开始删除最后一个nums06[:len(nums06)-1]。nums06的长度减一[root@www.linuxea.com /opt/Golang/work2]# cat make8.go package main import "fmt" func main(){ nums06 := []int{1,2,3,4,5} fmt.Println(nums06[1:]) fmt.Println(nums06[:len(nums06)-1]) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make8.go [2 3 4 5] [1 2 3 4]删除中间的元素使用copy来进行删除3。如下:nums06 := []int{1,2,3,4,5}或许索引2到结尾,和3到结尾的 fmt.Println(nums06[2:]) fmt.Println(nums06[3:])分别结果是[3 4 5]和[4 5]而后,在将nums06[3:] copy到nums06[2:]copy(nums06[2:],nums06[3:])如下图:如上图,索引3到结尾的值是4和5,copy到索引3结尾是3,4,5,结果就变成了[1 2 4 5 5]copy(nums06[2:],nums06[3:]) fmt.Println(nums06)而后在去掉最后一位,就变成了1,2,4,5fmt.Println(nums06[:len(nums06)-1])[1 2 4 5]代码块如下:[root@www.linuxea.com /opt/Golang/work2]# cat make8.go package main import "fmt" func main(){ nums06 := []int{1,2,3,4,5} fmt.Println(nums06) fmt.Println(nums06[2:]) fmt.Println(nums06[3:]) copy(nums06[2:],nums06[3:]) fmt.Println(nums06) fmt.Println(nums06[:len(nums06)-1]) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make8.go [1 2 3 4 5] [3 4 5] [4 5] [1 2 4 5 5] [1 2 4 5]3删除成功。4.9.2切片的应用a) 队列,先进先出从后面进行追加,移除的时候从前面开始移除[root@DT_Node-172_17_0_1 /opt/Golang/work2]# cat dmake4.go package main import "fmt" func main(){ queue := []int{} queue = append(queue,1,3,2) fmt.Println("queue:",queue) fmt.Println(queue[0]) queue = queue[1:] fmt.Println(queue[0]) queue = queue[1:] fmt.Println(queue[0]) queue = queue[1:] }运行[root@DT_Node-172_17_0_1 /opt/Golang/work2]# go run dmake4.go queue: [1 3 2] 1 3 2b) 堆栈,先进后出添加的时候往后添加,移除的时候也从后面移除。[root@DT_Node-172_17_0_1 /opt/Golang/work2]# cat dmake5.go package main import "fmt" func main(){ stack := []int{} stack = append(stack,1,3,2) fmt.Println("stack:",stack) fmt.Println(stack[len(stack) -1]) stack = stack[:len(stack)-1] fmt.Println(stack[len(stack)-1]) stack = stack[:len(stack)-1] fmt.Println(stack[len(stack)-1]) }运行[root@DT_Node-172_17_0_1 /opt/Golang/work2]# go run dmake5.go stack: [1 3 2] 2 3 1
2019年12月29日
1,968 阅读
0 评论
0 点赞
2019-12-28
linuxea:go切片公用的副作用(24)
示例说明:首先,我们创建一个切片,而后将进行赋值到另外一个变量,并且修改,观察发生的变化定义一个长度为3,容量为5的int类型的nums切片nums := make([]int,3,5)在声明一个nums02,nums02是从nums的切片生成的,start 1,end 3nums02 := nums[1:3]而后打印下两个变量的结果。fmt.Println(nums,nums02)如下。我们没有赋值,nums是三个0和nums02两个0[root@www.linuxea.com /opt/Golang/work2]# go run make6.go [0 0 0] [0 0]为了看出效果,我们修改nums02的索引0等于1,而后在打印nums02和nums nums02[0] = 1 fmt.Println(nums,nums02)运行如下:[root@www.linuxea.com /opt/Golang/work2]# go run make6.go [0 0 0] [0 0] [0 1 0] [1 0]图解在go中,nums02是用nums生成的[1:3],nums02和nums公用一个底层数组,这样一来,nums02指向的位置就是nums的索引1和索引3。如下图nums本身长度是3,表现为三个0。当nums02[0] = 1的时候,在修改nums02索引0等于1的同时,由于nums02和nums公用一个底层数组,打印nums,nums02的结果就是[0 1 0] [1 0]。在进行追加修改如下:如果此时给nums02 追加一个数。如下: nums02 = append(nums02,3) fmt.Println(nums,nums02)而后运行,得到的结果如下:[0 1 0] [1 0 3]这是因为nums本身长度为3,nums02追加的3不在nums长度范围内,所以nums中没有nums02追加的3。为了验证,我们在给nums追加一个5。这样一来,nums的长度从3变成了4,索引3位置将会发生改变。如下: nums = append(nums,5) fmt.Println(nums,nums02)运行[0 1 0 5] [1 0 5]这时候你会发现刚才nums02追加的3变成了5。这也是因为nums,nums02公用底层的数组导致。这就是两个切片公用底层的数组的副作用。而这种情况一直会持续到容量不够用重新申请新的底层数组。并且这种副作用也会延伸到数组中。如下:定义一个数组 arrays := []int{1,2,3,4,5} fmt.Println(arrays)赋值给nums,index省略表示len和cap nums = arrays[:] fmt.Println(nums,arrays)而后修改nums[0]等于100 nums[0] = 100 fmt.Println(nums,arrays)运行[root@www.linuxea.com /opt/Golang/work2]# go run make6.go [0 0 0] [0 0] [0 1 0] [1 0] [0 1 0] [1 0 3] [0 1 0 5] [1 0 5] [1 2 3 4 5] [1 2 3 4 5] [1 2 3 4 5] [100 2 3 4 5] [100 2 3 4 5]由此可见,对数组也是有 影响的。这是因为在切片的时候原理是一样的。代码块[root@www.linuxea.com /opt/Golang/work2]# cat make6.go package main import "fmt" func main(){ nums := make([]int,3,5) nums02 := nums[1:3] fmt.Println(nums,nums02) nums02[0] = 1 fmt.Println(nums,nums02) nums02 = append(nums02,3) fmt.Println(nums,nums02) nums = append(nums,5) fmt.Println(nums,nums02) arrays := []int{1,2,3,4,5} fmt.Println(arrays) nums = arrays[:] fmt.Println(nums,arrays) nums[0] = 100 fmt.Println(nums,arrays) }
2019年12月28日
1,925 阅读
0 评论
0 点赞
2019-12-20
linuxea:go切片的遍历切片操作(23)
遍历切片使用for range和len进行遍历两种简单方式4.8切片的遍历for lenfor循环遍历下nums,nums已经在上面定义了,加上之后如下:[root@www.linuxea.com /opt/Golang/work2]# cat make3.go package main import "fmt" func main(){ nums := make([]int,3,5) nums[2] = 100 nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) fmt.Println(nums) for i :=0;i<len(nums);i++{ fmt.Println(i,nums[i]) } }运行[root@www.linuxea.com /opt/Golang/work2]# go run make3.go [0 0 100 100 100 100 100 100] 0 0 1 0 2 100 3 100 4 100 5 100 6 100 7 100for range也可以使用for range遍历[root@www.linuxea.com /opt/Golang/work2]# cat make2.go package main import "fmt" func main(){ nums := make([]int,3,5) nums[2] = 100 nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) nums = append(nums,100) fmt.Println(nums) for index,key := range nums { fmt.Println(index,key) } }运行[root@www.linuxea.com /opt/Golang/work2]# go run make2.go [0 0 100 100 100 100 100 100] 0 0 1 0 2 100 3 100 4 100 5 100 6 100 7 1004.9切片的操作获取3个的元素nums[0:3]顺便查看切片的类型fmt.Printf("%T",nums[0:3])代码块:package main import "fmt" func main(){ nums := make([]int,3,5) nums[2] = 100 nums = append(nums,101) nums = append(nums,102) nums = append(nums,103) nums = append(nums,104) nums = append(nums,105) fmt.Println(nums) fmt.Println(nums[0:3]) fmt.Printf("%T",nums[0:3]) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make4.go [0 0 100 101 102 103 104 105] [0 0 100] []int切片的类型也是一个切片([]int )切片的第三个元素此前,在数组中是有第三个元素的,而在切片中也是有的。定义一个新切片,长度为3,容量为10的int类型:nums := make([]int,3,10)而后重新声明为n,打印元素,长度,容量。n := nums[1:3:10] fmt.Println(n) fmt.Printf("%T %#v %d %d\n",n,n,len(n),cap(n))这里获取的容量是通过n的END减去n的start,在上面代码中就是10-1,容量是9,长度是2。如下:[root@www.linuxea.com /opt/Golang/work2]# go run make5.go [0 0] []int []int{0, 0} 2 9如果是两个元素呢,定义一个n2,如下:nums := make([]int,3,10) n2 := nums[2:3] fmt.Println(n2) fmt.Printf("%T %#v %d %d\n",n2,n2,len(n2),cap(n2))代码块[root@www.linuxea.com /opt/Golang/work2]# cat make5.go package main import "fmt" func main(){ nums := make([]int,3,10) n2 := nums[2:3] fmt.Printf("%T %#v %d %d\n",n2,n2,len(n2),cap(n2)) }两个元素获取的容量是nums的cap减去n2的start的结果,以上代码中的容量结果是8。n2的长度是1,容量是8。这和三个元素的结果是有差异的。如下:[root@www.linuxea.com /opt/Golang/work2]# go run make5.go [0] []int []int{0} 1 8总结当使用第三个元素切片操作的时候,获取的容量是END(第三个元素)值减去索引的START(开始),得到的是新赋值的容量值。当使用两个元素切片操作,获取的容量是容量减去索引start。但是都不能超过make原来的的容量。这里所值的END和START 是索引的位置。
2019年12月20日
2,179 阅读
0 评论
0 点赞
2019-11-23
linuxea:go切片元素的获取修改和添加(22)
接着切片的声明和赋值,现在索引获取切片元素。定义长度是5,元素3,赋值给nums,如下获取元素 nums := make([]int,3,5)获取元素使用nums[0]开始进行获取,如下 fmt.Println(nums[0]) fmt.Println(nums[1]) fmt.Println(nums[2])运行[root@www.linuxea.com /opt/Golang/work2]# cat make.go package main import "fmt" func main(){ nums := make([]int,3,5) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) fmt.Println(nums[0]) fmt.Println(nums[1]) fmt.Println(nums[2]) }如果你获取的元素超出了长度,就会抛出panic,如:goroutine 1 [running]: main.main() /opt/Golang/work2/make.go:9 +0x2ab exit status 24.6切片元素修改修改第三个元素是100 nums[2] = 100这里的索引就是2,因为从0到2是三如下:package main import "fmt" func main(){ nums := make([]int,3,5) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) fmt.Println(nums[0]) fmt.Println(nums[1]) fmt.Println(nums[2]) nums[2] = 100 fmt.Println(nums) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make.go []int{0, 0, 0} 3 5 0 0 0 [0 0 100]4.7切片元素添加切片通过append进行添加,如下: nums = append(nums,100)append添加的时候会返回一个值,将返回值赋值到nums。而后在打印下长度和容量 fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums))[root@www.linuxea.com /opt/Golang/work2]# cat make.go package main import "fmt" func main(){ nums := make([]int,3,5) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) fmt.Println(nums[0]) fmt.Println(nums[1]) fmt.Println(nums[2]) nums[2] = 100 fmt.Println(nums) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make.go []int{0, 0, 0} 3 5 0 0 0 [0 0 100] []int{0, 0, 100, 100} 4 5如上,最下面那行中,可以看到长度从之前的3,在执行append后变成4,容量还是5。如果继续添加元素,容量在超过5后,容量会随着长度自动增长。增长的个数如:[root@www.linuxea.com /opt/Golang/work2]# cat make.go package main import "fmt" func main(){ nums := make([]int,3,5) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) fmt.Println(nums[0]) fmt.Println(nums[1]) fmt.Println(nums[2]) nums[2] = 100 fmt.Println(nums) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) nums = append(nums,100) fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums)) }运行[root@www.linuxea.com /opt/Golang/work2]# go run make.go []int{0, 0, 0} 3 5 0 0 0 [0 0 100] []int{0, 0, 100, 100} 4 5 []int{0, 0, 100, 100, 100} 5 5 []int{0, 0, 100, 100, 100, 100} 6 10 []int{0, 0, 100, 100, 100, 100, 100} 7 10 []int{0, 0, 100, 100, 100, 100, 100, 100} 8 10可以看到,当长度超过容量后,容量就会自动增加。增加多少取决于扩展的算法。图解append扩展数组的空间是连续的。比如说,make一个长度为3,容量为5的int切片,长度为3将会填充0,1,2索引位。make([]int,3,5)如下图:go会自动申请好底层数组以供使用,当我们打印int类型的切片索引的时候,显示为0如上图,当append追加一个元素100的时候,就会占用一个数组容量,这个过程对于底层的数组是不会变的,图中因为容量是5,而现在append后长度是4。在追加一个101,也不会变,长度和容量持平。如果继续追加102,如:nums = append(nums,102)此时底层数组就不够用了。这时候就会重新申请数组。而这个数组的长度也是会进行扩展,扩展是根据扩展的算法进行计算。通常是成倍增加。并且,底层数组也会指向到新的数组之上。如下:事实上,当底层数组修改后,nums数组指针指向也会被修改指向新的地址,而后在使用nums接收,也就是赋值给numsnums = append(nums,100)
2019年11月23日
2,785 阅读
0 评论
0 点赞
1
2
3
...
5