浅析Go语言中的Range关键字

前言

相信用过Range的朋友们都知道,Go语言中的range关键字使用起来非常的方便,它允许你遍历某个slice或者map,并通过两个参数(indexvalue),分别获取到slice或者map中某个元素所在的index以及其值。

比如像这样的用法:

for index, value := range mySlice {
 fmt.Println("index: " + index)
 fmt.Println("value: " + value)
}

上面的例子足够清晰的描述了range的用法,实际上在使用range关键字的时候,还有一些需要特别注意的地方,有一些新手很容易入的”坑”。

为了说明这些”坑”,我们可以从下面这个稍复杂的例子说起:

type Foo struct {
 bar string
}
func main() {
 list := []Foo{
 {"A"},
 {"B"},
 {"C"},
 }
 list2 := make([]*Foo, len(list))
 for i, value := range list {
 list2[i] = &value
 }
 fmt.Println(list[0], list[1], list[2])
 fmt.Println(list2[0], list2[1], list2[2])
}

在这个例子中,我们干了下面的一些事情:

1、定义了一个叫做Foo的结构,里面有一个叫bar的field。随后,我们创建了一个基于Foo结构体的slice,名字叫list

2、我们还创建了一个基于Foo结构体指针类型的slice,叫做list2

3、在一个for循环中,我们试图遍历list中的每一个元素,获取其指针地址,并赋值到list2中index与之对应的位置。

4、最后,分别输出list与list2中的每个元素

从代码来看,理所当然,我们期望得到的结果应该是这样:

{A} {B} {C}

但是结果却出乎意料,程序的输出是这样的:

{A} {B} {C}

从结果来看,仿佛list2中的三个元素,都指向了list中的最后一个元素。这是为什么呢?问题就出在上面那一段for…range循环中。

在Go的for…range循环中,Go始终使用值拷贝的方式代替被遍历的元素本身,简单来说,就是for…range中那个value,是一个值拷贝,而不是元素本身。这样一来,当我们期望用&获取元素的指针地址时,实际上只是取到了value这个临时变量的指针地址,而非list中真正被遍历到的某个元素的指针地址。而在整个for…range循环中,value这个临时变量会被重复使用,所以,在上面的例子中,list2被填充了三个相同的指针地址,并且这三个地址都指向value,而在最后一次循环中,value被赋与了{c}的指针地址。因此,list2输出的时候显示出了三个

同样的,下面的写法,跟for…range的例子如出一辙:

var value Foo
for var i := 0; i < len(list); i++ {
 value = list[i]
 list2[i] = &value
}

如果我们输出list2的三个元素,结果同样是:

那么,怎样才是正确的写法呢?我们应该用index来访问for…range中真实的元素,并获取其指针地址:

for i, _ := range list {
 list2[i] = &list[i]
}

这样,输出list2中的元素,就能得到我们想要的结果()了。

实验代码如下:

package main

import "fmt"

type Foo struct {
 bar string
}

func main() {
 list := []Foo{
 {"A"},
 {"B"},
 {"C"},
 }

 list2 := make([]*Foo, len(list))

 //错误的例子
 for i, value := range list {
 list2[i] = &value
 }

 //正确的例子
 //for i, _ := range list {
 // list2[i] = &list[i]
 //}

 fmt.Println(list[0], list[1], list[2])
 fmt.Println(list2[0], list2[1], list2[2])
}

了解了range的正确使用姿势,那么我们下面这个例子也能迎刃而解了:

package main
import "fmt"
type MyType struct {
 field string
}
func main() {
 var array [10]MyType
 for _, e := range array {
 e.field = "foo"
 }
 for _, e := range array {
 fmt.Println(e.field)
 fmt.Println("--")
 }
}

平常写代码最常见的场景,就是我们需要在一个循环中修改被遍历元素的值。比如上面这个例子,我们希望能使用for…range循环,一次性将array中每个元素的field设置为”foo”。同样,因为range值拷贝的缘故,上面的程序什么都不会输出……

而正确的做法是:

for i, _ := range array {
 array[i].field = "foo"
}

通过index访问每个元素,并修改其field,这样,就能输出一堆”foo”了……

实验代码如下:

package main

import "fmt"

type MyType struct {
 field string
}

func main() {
 var array [10]MyType

 for i, _ := range array {
 array[i].field = "foo"
 }

 for _, e := range array {
 fmt.Println(e.field)
 }
}

总结

以上就是关于Go语言中Range关键字的全部内容,这篇文章介绍的还是很详细的,相信本文会对大家学习Go语言具有一定的参考价值,如果有疑问大家可以留言交流,小编会尽快给大家回复的,也请大家继续支持我们。

时间: 2016-09-08

vim配置显示行号和语法高亮 即.vimrc文件的配置

在终端下使用vim进行编辑时,默认情况下,编辑的界面上是没有显示行号.语法高亮度显示.智能缩进等功能的. 为了更好的在vim下进行工作,需要手动设置一个配置文件:.vimrc. 在启动vim时,当前用户根目录下的.vimrc文件会被自动读取,该文件可以包含一些设置甚至脚本,所以,一般情况下把.vimrc文件创建在当前用户的根目录下比较方便,即创建的命令为: $vi ~/.vimrc 设置完后 $:x 或者 $wq 进行保存退出即可. 下面给出一个例子,其中列出了经常用到的设置,详细的设置信息请参

PHP语法自动检查的Vim插件

由于最近写PHP比较多,偶尔手误少写个分号之类的语法错误难免,一般的检查方式是回到命令行运行 php -l ,或者升级一下直接在Vim里运行 :!php -l % ,或者再将此绑定为快捷键,如 :map <F5> :!php -l %<CR> ,每当按F5便可立即执行语法检查.但还是觉得略有不爽,因为很多IDE是实时检查的,语法错误会提示在代码行的旁边.虽然实时检查未必有必要,但自动检查要比手动检查方便的多,比如在php文件保存时自动执行检查. 于是写了这个 phpcheck.vi

go语言环境搭建简述

$tar xvf go1.3.3.linux-amd64.tar.gz $mv go /usr/local/ $vim /etc/profile export GOROOT=/usr/local/go export PATH=$PATH:$GOROOT/bin $source /etc/profile 至此,go安装完毕. 如需更详细的安装步骤,请联系我.

利用Go语言初步搭建一个web应用的教程

1.Abstract 在学习web开发的过程中会遇到很多困难,因此写了一篇类似综述类的文章.作为路线图从web开发要素的index出发来介绍golang开发的学习流程以及Example代码. 在描述中多是使用代码来描述使用方法不会做过多的说明.最后可以方便的copy代码来实现自己的需求. 本文适应对象: 对web开发有一定经验的人 能够灵活使用ajax的人(至少懂得前后分离) golang web 开发有一定了解,至少略读过一些golang web开发的书籍 看完本文之后您会收获: golang

Go语言开发环境搭建与初探(Windows平台下)

Go语言开发环境的搭建(Windows) Windows下的Go语言开发安装包 官方下载地址: https://code.google.com/p/go/downloads/list 我们下载地址:http://www.jb51.net/softs/237132.html Go语言中文官网(有相关参考和文档) http://zh.golanger.com/ 方法/步骤 1.在Go语言的Google代码项目上下载Windows下的Go语言开发包(下载地址见工具).有zip压缩版和msi安装版两个按

google 搜索框添加关键字实现代码

可以让你向你的用户建议搜索的关键词.要注意: 改变搜索框的代码是违反Google政策的, 但是,这段代码是独立于搜索代码之外的,尽管它确实影响了搜索框的输入. 如下,随便用你希望的搜索关键词代替以下代码中的ABC,DEF和GHI,当用户点击这些关键词的时候,它们就会自动 出现在搜索框中. 复制代码 代码如下: // change forms[0] to forms[n] as needed. <SCRIPT language="JavaScript"> function s

Centos下搭建golang环境及vim高亮Go关键字设置的方法

一.Centos搭建go环境 1:下载  https://golang.org/dl/ 下载        go1.4.1.Linux-amd64.tar.gz           ArchiveLinux64-bit 2:切换sudo权限解压到/usr/local/目录下  tar xzvf go1.4.1.linux-amd64.tar.gz -C /usr/local/ 3:返回普通用户权限 4:设置PATH vi ~/.bash_profile export GOROOT=/usr/lo

解决vim语法高亮不起作用的方法

一.首先将vim更新为最新版yum -y install vim,并安装Vim的加强版vim-enhanced ,以安装支持彩色的组件    yum -y install vim-enhanced 二.接下来配置vim配置文件  vi   /etc/vimrc     增加一行  syntax on 或者我们干脆下载个干净版的vimrc吧 三.为了让vi命令也可以使用vim的配置,需要修改   vi /etc/bashrc        增加一行   alias vi='vim' 此时,经过上面

Mac OS X中设置VIM语法高亮的方法

前言 Vim 是一款相当给力的源自UNIX平台的命令行文本编辑器,不过不给力的是,Mac OS X下并没有诸多Linux发行版上VIM那些牛逼哄哄的神马代码高亮显示啊,自动缩进之类的. (译者注:通常Linux发行版可以通过编辑/etc/vimrc文件更改全局VIM设定或者针对某个用户的~/.vimrc进行个性化配置) 为了弥补这个缺憾,请按如下方法操作: 实现方法 主要是修改~/.vimrc文件 文件内容如下: set ai " auto indenting set history=100 &

ubuntu下搭建Go语言(golang)环境

Go语言是谷歌2009发布的第二款开源编程语言.Go语言专门针对 多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全.支持并行进程. 还是我自己的电脑,我自己安装的是ubuntu 12.04版本的,直接介绍安装吧!其实搭建环境很简单! 复制代码 代码如下: sudo apt-get install python-setuptools python-dev build-essential //安装mercurial依赖 sudo easy_insta

Ubuntu下安装Go语言开发环境及编辑器的相关配置

安装 Windows下是直接的安装包,这里我们略过,来看一下Ubuntu下安装Go: sudo add-apt-repository ppa:gophers/go sudo apt-get update sudo apt-get install golang-stable 或 sudo apt-get install golang 或者直接下载go语言安装包 环境配置: vi /etc/profile 加入 export GOROOT=/usr/lib/go export GOARCH=386

Linux(Ubuntu)下搭建ASP.NET Core环境

今天来学习一下ASP.NET Core 运行在Ubuntu中.无需安装mono . 环境 Ubuntu 14.04.4 LTS 服务器版 全新安装系统. 下载地址:http://mirrors.neusoft.edu.cn/ubuntu-releases/14.04.4/ubuntu-14.04.4-server-amd64.iso 你也可以下载桌面版安装. 下载地址:http://mirrors.neusoft.edu.cn/ubuntu-releases/14.04.4/ 安装DNVM 首先

在ubuntu下构建go语言开发环境的方法

新版本的go有更好的性能,ubuntu软件库只有交旧的版本,通过源码安装go1.2 具体步骤: 1.去官网下载go1.1.2的tarball,我下载到tem目录 2.打开终端cd /usr/local, tar -zxvf go1.1.2.linux-386.tar.gz 将源码文件解压缩到/usr/local目录,如果解压到其他目录,需要自己设置GOROOT 3.安装gcc工具,因为golang有些功能是使用c写 sudo apt-get install bison gawk gcc libc

在Linux(Ubuntu)下搭建PHP环境的操作步骤

一.安装Apache2 sudo apt-get install apache2 二.测试Apache2 在地址栏输入以下地址,出现如图所示照片,则表明安装成功 http://localhost/ 三.重启apache2服务 sudo /etc/init.d/apache2 restart //'restart'->'stop'关闭服务; 'restart'->'start'启动服务 四.安装PHP sudo apt-get install php5 libapache2-mod-php5 `

搭建C语言开发环境(Windows平台)汇总

新接触C语言,如何进行C语言开发环境的搭建值得思考并整理 一.在Windows平台配置GNU环境 GNU http://www.gnu.org/ 选择以下GNU环境下载安装到C盘: 1.MinGw 官网下载安装 http://www.mingw.org/ 本站高速下载安装 http://www.jb51.net/softs/192011.html 将C:\MinGW\msys\1.0\msys.bat 发送到桌面快捷方式 在msys.bat命令框中输入 gcc 会得到:sh: gcc: comm

CentOS 7下配置Ruby语言开发环境的方法教程

本文跟大家分享的是在CentOS 7下配置Ruby语言开发环境的方法教程,分享出来供大家参考学习,下面来看看详细的介绍: 安装Ruby 2.2 CentOS7存储库中的Ruby版本为2.0,但如果需要,可以使用RPM软件包安装2.2 1.添加CentOS SCLo软件集合存储库 [root@linuxprobe ~]# yum -y install centos-release-scl-rh centos-release-scl # set [priority=10] [root@linuxpr

在Mac中搭建go语言开发环境的操作步骤

前言 Go语言是Google内部主推的语言,它作为一门全新的静态类型开发语言,与当前的开发语言相比具有许多令人兴奋不已的新特性.专门针对多处理器系统的应用程序编程进行了优化,使用go语言完全可以媲美c.c++的速度,而且更加安全.简洁,支持并行进程. 以下是go语言的主要特性: 1.自动垃圾回收 2.更丰富的内置类型 3.函数多反回值 4.错误处理 5.匿名函数和闭包 6.类型和接口 7.并发编程 8.反射 9.语言交互性 Mac开发环境搭建 以上基本都属废话,搭建开发环境尽快开启编程之旅才是王

在Ubuntu下搭建Android开发环境

1.安装JDK 其实这一步我比较偷懒,在网上查了一下Ubuntu系统下安装JDK的方法,看起来稍稍有点麻烦,于是我试着在自带的软件中心里搜了一下,然后发现在软件中心里有个OpenJDK Java 7,尝试着安装后,发现这是个好东西,一键安装后环境变量什么的都已经自动配好了,eclipse什么的都能自动识别,很方便.百度了一下Open JDK和sun JDK的区别,大概就是sun公司的JDK是在Open JDK的基础上开发的,扩展了一些东西.经过这段时间的使用,在开发Android的时候没发现有什

ubuntu下搭建php开发环境(nginx+(cgi)php5fpm+memcached+xdebug)

由于只是开发环境,所以都是选择比较简单的apt-get安装方式 ,但中间也遇到一点问题. 首先安装nginx nginx的安装和配置其实很简单,nginx本身非常轻量级, 直接 sudo apt-get install nginx 就可以了 他的配置文件是在/etc/nginx/里面,网站项目路径是在/var/www里面,安装之后一定要确保nginx的启动账户有对网站目录的访问权限,否则会报错. 第二步,安装cgi linux底下的cgi程序非常多,在这里我选择的是php5-fpm 方便  在这