首页 > 其他分享 >Go-map、切片、数组循环常见问题总结

Go-map、切片、数组循环常见问题总结

时间:2023-06-16 10:46:52浏览次数:52  
标签:map 常见问题 fmt Println range func time Go main

map

1、for range map 在开始执行循环的时候,底层做了随机种子,故其循环是随机的。

package main
import "fmt"
func main() {
	a := map[int]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for _, c := range a {
		fmt.Println(c)
	}
}

输出: 3 4 5 1 2 多次执行,结果不同

数组

package main

import "fmt"

func main() {

	a := [5]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for b, c := range a {
		if b == 0 {
			a[1] = 22
			//fmt.Println(b)
		}
		a[b] = c + 10
	}
	fmt.Println(a)
}

输出: [11 12 13 14 15]

//a[1] = 22 并没有起作用,因数组是值类型,使用range获取的数组项是复制过来的,并非引用原始数据。

如果想a[1] = 22 有效,只需改成引用。

package main

import "fmt"

func main() {

	a := [5]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	
	for b, c := range &a {//注意此处改变
		if b == 0 {
			a[1] = 22
			//fmt.Println(b)
		}
		a[b] = c + 10
	}
	fmt.Println(a)
}

结果: [11 32 13 14 15]

slice

slice 是引用类型,底层指针指向数组,传参的时候传引用和传值区别不大。

示例1

package main

import "fmt"

func main() {

	a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for b, c := range a {
		if b == 0 {
			a[1] = 22
			//fmt.Println(b)
		}
		a[b] = c + 10
	}
	fmt.Println(a)
}

结果: [11 32 13 14 15] 对比上一个例子,不需要传引用就可以更改a[1] = 22

示例2

这个是输出异常的示例

package main

import (
"fmt"
)

func main() {

	a := []int{1, 2, 3}
	b := make([]*int, len(a))

	for i, v := range a {
		//解决办法1增加临时变量
		//vv := v
		//b[i] = &vv
		//解决办法2   
		//b[i] = &a[i]
		b[i] = &v
	}
	for _, v := range b {
		fmt.Println(*v)
	}
}

输出: 3 3 3

原因v变量在for range中只会创建一次,之后迭代重复使用

迭代闭包容易出问题

package main

import (
	"fmt"
	"time"
)

func main() {
	a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for _, c := range a {
	
		go func() {
			fmt.Println(c)
		}()
	}
	time.Sleep(3 * time.Second)

}

结果为: 3 3 5 5 5 有两种方法解决以上问题

1、增加一个临时变量

package main

import (
	"fmt"
	"time"
)

func main() {
	a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for _, c := range a {
		cc:=c //增减临时变量cc
		go func() {
			fmt.Println(cc)
		}()
	}
	time.Sleep(3 * time.Second)

}

2、 传参进去

package main

import (
	"fmt"
	"time"
)

func main() {
	a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
	for _, c := range a {
		go func(c int) {
			fmt.Println(c)
		}(c)
	}
	time.Sleep(3 * time.Second)

}

循环子协程

package main

import (
	"fmt"
	"time"
)

type v struct {
	value int
}

func (vv *v) show() {
	fmt.Println(vv.value)
}
func main() {
	a := []v{{1}, {2}, {3}}
	for _, c := range a {
		go c.show()
	}
	time.Sleep(3 * time.Second)
}

输出: 3 3 3 解决办法 1、增加临时变量

package main

import (
	"fmt"
	"time"
)

type v struct {
	value int
}

func (vv *v) show() {
	fmt.Println(vv.value)
}
func main() {
	a := []v{{1}, {2}, {3}}
	for _, c := range a {
		c := c //增加这一行
		go c.show()
	}
	time.Sleep(3 * time.Second)
}

2、使用指针

package main

import (
	"fmt"
	"time"
)

type v struct {
	value int
}

func (vv *v) show() {
	fmt.Println(vv.value)
}
func main() {
	a := []*v{{1}, {2}, {3}}
	for _, c := range a {
		go c.show()
	}
	time.Sleep(3 * time.Second)
}

3、方法show接受者不用指针

package main

import (
	"fmt"
	"time"
)

type v struct {
	value int
}

func (vv v) show() {
	fmt.Println(vv.value)
}
func main() {
	a := []v{{1}, {2}, {3}}
	for _, c := range a {
		go c.show()
	}
	time.Sleep(3 * time.Second)
}

标签:map,常见问题,fmt,Println,range,func,time,Go,main
From: https://www.cnblogs.com/minch/p/17484967.html

相关文章

  • AtCoder Beginner Contest 251 G Intersection of Polygons
    洛谷传送门AtCoder传送门经典结论,一个点\(P(x,y)\)在一个凸多边形内部\(S=\{(x_i,y_i)\}\)的充要条件是\(\foralli\in[1,n],(x_{i+1}-x_i,y_{i+1}-y_i)\times(x-x_i,y-y_i)\ge0\),其中\(S\)的点按照逆时针排列。然后我们运用叉积的一个性质......
  • golang之数据验证validator
    https://blog.csdn.net/guyan0319/article/details/105918559/前言在web应用中经常会遇到数据验证问题,普通的验证方法比较繁琐,这里介绍一个使用比较多的包validator。原理将验证规则写在struct对字段tag里,再通过反射(reflect)获取struct的tag,实现数据验证。安装gogetgithub.co......
  • golang之context
    context用来解决goroutine之间退出通知、元数据传递的功能。 context使用起来非常方便。源码里对外提供了一个创建根节点context的函数:funcBackground()Context background是一个空的context,它不能被取消,没有值,也没有超时时间。有了根节点context,又提供了......
  • 用Scrum工具Leangoo领歌做敏捷需求管理
    传统的瀑布工作模式使用详细的需求说明书来表达需求,需求人员负责做需求调研,根据调研情况编制详细的需求说明书,进行需求评审,评审之后签字确认交给研发团队设计开发。在这样的环境下,需求文档是信息传递的主体,也是一份契约。然而详细的需求说明书有以下5大弊端:单向的信息传递,容易......
  • Jackson2ObjectMapperBuilderCustomizer
    //序列化时的命名策略——驼峰命名法builder.propertyNamingStrategy(PropertyNamingStrategy.LOWER_CAMEL_CASE);配置作用  ......
  • Oracle最高可用性架构(MAA)|黄金级(GOLD)
    1、什么是MAA参考之前的文章:1、Oracle最高可用性架构(MAA)|青铜级(BRONZE)https://www.cnblogs.com/mingfan/p/16804556.html2、Oracle最高可用性架构(MAA)|白银级(SILVER) https://www.cnblogs.com/mingfan/p/17464913.html2、黄金级(GOLD)MAA我们都知道,单点是系统高可用的......
  • Django学习笔记
    1、安装djangopipinstall-Udjango#安装django 2、创建django工程、启动工程创建项目django-adminstartprojectdjango_test #安装完django后会有django-admin命令#django_test是项目名称,创建项目时修改为自己的项目名称即可启动项目项目创建完成后,会在执行命令......
  • @MapKey is required
    @MapKeyisrequired 这就是mybatis的annotation的一个提醒,可以直接忽略,不影响代码编译;为啥出现这种情况,因为我们很烂,sql中返回的对象不愿意定义一个 resultMap,select默认就是返回list,不指定resultMap或者resultType,默认就是组装为map对象返回;注意:一定要指定 resultType="......
  • celery笔记四之在Django中使用celery
    本文首发于公众号:Hunter后端原文链接:celery笔记四之在Django中使用celery这一篇笔记介绍一下如何在Django系统中使用celery。如果是想纯粹使用celery,这一篇笔记可以略过。本篇笔记目录如下:文件配置task定义运行worker1、文件配置我们这里使用前面的创建的hunt......
  • django 设置定时任务
    django设置定时任务,网上百度了好几种方式,试了这两种方式,简单有效:例如,我们要设置最简单的执行场景,5s输出一次helloworld。(1)通过whileTrue设置定时任务importtimedefrun():print("hello,world")if__name__=='__main__':whileTrue:run()......