白云岛资源网 Design By www.pvray.com

前言

在Golang中使用 for range 语句进行迭代非常的便捷,但在涉及到指针时就得小心一点了。

下面的代码中定义了一个元素类型为 *int 的通道 ch :

package main

import (
 "fmt"
)

func main() {
 ch := make(chan *int, 5)
 
 //sender
 input := []int{1,2,3,4,5}
 
 go func(){
  for _, v := range input {
   ch <- &v
  }
  close(ch)
 }()
 //receiver
 for v := range ch {
  fmt.Println(*v)
 }
}

在上面代码中,发送方将 input 数组发送给 ch 通道,接收方再从 ch 通道中接收数据,程序的预期输出应该是:

现在运行一下程序,得到的输出如下:

很明显,程序并没有达到预期的结果,那么问题出在哪里呢?我们将代码稍作修改:

//receiver
  for v := range ch {
    fmt.Println(v)
  }

得到如下输出:

0x416020
0x416020
0x416020
0x416020
0x416020

可以看到,5次输出变量 v ( *int )都指向了同一个地址,返回去检查一下发送部分代码:

for _, v := range input {
  ch <- &v
}

问题正是出在这里,在 for range 语句中, v 变量用于保存迭代 input 数组所得的值,但是 v 只被声明了一次,此后都是将迭代 input 出的值赋值给 v , v 变量的内存地址始终未变,这样再将 v 的地址发送给 ch 通道,发送的都是同一个地址,当然无法达到预期效果。

解决方案:

引入一个中间变量,每次迭代都重新声明一个变量 temp ,赋值后再将其地址发送给 ch :

for _, v := range input {
  temp := v
  ch <- &temp
}

抑或直接引用数据的内存(推荐,无需开辟新的内存空间):

for k, _ := range input {
  c <- &input[k]
}

再次运行,就可看到预期的效果。以上方案是用于讨论 range 语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

白云岛资源网 Design By www.pvray.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
白云岛资源网 Design By www.pvray.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。