初识Go语言之变量

var声明创建一个具体类型的变量,然后给它附加一个名字,设置他的初始值,这种声明都是一个通用的形式:

var name type = expression

在实际的开发中,为了方便开发,我们一般不会这么写,我们会省略type或者expression,因为省略了type,编译器会由expression推断出type的值,而省略了expression,编译器会给变量自动赋值为零值,就是常见的nil。
不同类型的零值如下表所示:

type 零值
int 0
boolean false
string ""
slice nil
pointer nil
map nil
通道 nil
函数 nil

零值的设计对于在实际开发中对程序员是非常有好的,因为我们不需要花费额外的精力使得一个复杂的类型的零值有意义,使得变量一开始就是一个可用的状态。这点作为Java开发者,我们深有体会,以你为一个变量如果在声明的时候没有复制,编译器就会提示报错。这点在Go里面就得到了很好的解决。

var s string
fmt.Println(s) //  ""

当然,我们也可以同时声明多个具有相同类型或者不同类型的变量,如下所示:

var i,j,k int
var b,f,s = true,4,"Hello"

此外,变量可以通过调用返回多个值的函数进行初始化:

var f,err = os.open(name) //os.open()返回一个文件和一个错误

短变量声明

在Go里面可以使用短变量声明的方式来实现变量的声明和初始化,如下:

l := 3

这种短小、灵活的局部变量声明方式非常受欢迎,在实际开发工作中十分常用。但是在全局变量的声明,我们依然建议您使用var来声明。

此外对短变量声明,需要注意如下情况,至少要声明一个新变量,否则编译将无法通过

# 正确的写法
in,err := os.open(infile)
out,err := os.open(infile)
# 错误的写法,编译将无法通过
f,err := os.open(infile)
f,err := os.open(infile)

指针

指针的值是一个变量的地址,一个指针指示值保存的位置,使用指针可以间接读取或者更新变量的值。

如果一个变量声明为var x int,表达式&x(x的地址)获取一个指向整型变量的指针,它的类型是整型指针(*int),如果值叫做p,我们就说p 指向x的地址。p 指向的变量写成 *p。

x:=1
p:=&x // p是整型指针,指向x
fmt.Print(*p) //"1"
*p := 2 // 相当于x=2

注意:
指针类型的变量的零值为nil,如果我们测试 p != nil,则说明p指向一个变量的地址。同时,指针也是可以比较的,两个指针当且仅当指向同一个变量或者两者相等都是nil的情况下才相等。

var x, y int
fmt.Println(&x == &x,&x == &y, &x == nil) // true ,false, false

函数返回局部变量的地址是非常安全的,如下:

var p  = f()
func f() *int{
v := 1
return &v
}

每次调用都会返回一个不同的值:

fmt.Println(f() == f())//false

因为指针包含变量的地址,所以传递一个指针参数给函数,能够让函数更新间接传递的变量值。

func incr(p *int) int {
*p++//递增p所指向的值;P本身不变
return *p
}
v := 1
incr(&v) // 副作用:v现在等于2
fmt.Println(incr(&v))//"3"(v现在是3)

new函数

new函数是Go内置的创建变量的函数,表达式new(T)可以创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(*T)。

p:=new(int)//*int类型的p,指向未命名的int变量
fmt.Println(p)//0
*p := 2 // 把未命名的int设置为2
fmt.Println(2)

注意:
使用new创建的变量和普通取地址的普通变量没有区别,只是用new创建的变量,不需要用一个别名来专门取变量的地址。

如下所示,两块代码其实意义是一样的
new函数方式:

func newInt() (*int){
return new(int)
}

普通方式:

func newInt() (*int){
var i int
return &i
}

变量的生命周期

变量的生命周期指在程序执行过程中变量存活的时间区间。包级别的生命周期是整个程序的执行时间。相反,局部变量有一个动态的生命周期:每次执行声明语句时创建一个新的实体,变量一直存活到其不可访问为止,,这时就会被GC回收。值得注意的是,函数的参数和返回值也是局部变量。
我们来看个例子哈:

var global *int
func f(){
var x int 
x = 1
glbal = &x
}

func f(){
y := new(int)
*y = 1
}

这里X一定是使用堆空间的,因为在f函数返回后,x依然可以被global访问。g函数返回后,变量*y就会变得不可访问,因此g返回后,*y就会被回收。

如果您有任何问题,欢迎与我私信交流~

Go语言程序结构之变量的更多相关文章

  1. Objective-C 学习笔记(一) 语言程序结构

    Objective-C语言程序结构 “Hello World”简单示例 #import <Foundation/Foundation.h> //预处理命令,它告诉Objective-C语言 ...

  2. 个人学习笔记:C语言程序结构

    个人笔记:C语言程序 函数 语句 输入输出对象 标识符 关键字 函数 一个C语言源程序,是由一个或多个函数定义顺序组成的,其中必须有一个函数名为main的主函数.C语言源程序中的函数是指完成特定数据处 ...

  3. 【值得收藏】C语言入门基础知识大全!从C语言程序结构到删库跑路!

    01 C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { ...

  4. C语言中结构体变量之间赋值

    近期,我阅读了某新员工小刘写的C语言代码,发现其对结构体变量之间的赋值不是非常熟悉. 对于两个同样类型的结构体变量,他均採用的是逐个成员变量直接赋值的形式.例如以下的代码演示样例: 如上代码所看到的, ...

  5. C语言 指向结构体变量的指针

    一个指向变量的指针表示的是占内存中起始位置 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组 定义结构体变量的指针: //假设已有一个结构体名为Stu ...

  6. 【Go语言系列】2.3、Go语言基本程序结构:变量及常量

    1.什么变量 变量来源于数学,从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间. 1.1变量声明 Go 语言变 ...

  7. Go语言程序结构

    注意:Go语言源码文件编码格式必须是 UTF-8 格式,否则会导致编译器出错. 1.语言变量 a) 指定变量类型,声明后若不赋值,使用默认值. var name string b) 根据值自行判定变量 ...

  8. C语言_结构体变量指针做函数参数的使用案例

    # include <stdio.h> # include <stdlib.h> # include <string.h> # include <malloc ...

  9. Python的程序结构[3] -> 变量/Variable[0] -> 变量类型

    变量类型 / Variable Type 在 Python 中,变量主要有以下几种,即全局变量,局部变量和内建变量, 全局变量 / Global Variable 通常定义于模块内部,大写变量名形式存 ...

随机推荐

  1. storm卡顿修改

    ​ 最近的webstorm越来越卡了,有时候甚至会弹出 Out of memory的窗口,提示要设置 xmx的值, 8G内存跑你这小软件还会不够用???要内存?给你,看你还会不会卡成翔! 于是果断给x ...

  2. 回归本心QwQ背包问题luogu1776

    今天在这里说一下多重背包问题 对 之前一直没有怎么彻底理解 首先多重背包是什么?这里就不做过多的赘述了 朴素的多重背包的复杂度是\(O(n*m*\sum s[i])\),其中\(s[i]\)是每一件物 ...

  3. 使用包图 (UML Package Diagram) 构建模型架构

    包图用于以包包含层次结构的形式显示模型的组织方式.包图还可以显示包包含的模型元素以及包与其包含的模型元素之间的依赖关系. 在项目开发中,模型元素可能会很快达到大量数量,因此需要以某种方式构建它们,即使 ...

  4. 离线状态迁移Anaconda虚拟环境

    离线状态迁移Anaconda虚拟环境 同样是项目需求,需要布署的服务器上的Anaconda安装到了普通账户下 而后续所有的内容都需要通过root账户进行操作,而服务器已经布署,联网比较麻烦 本文提出, ...

  5. mybatis学习笔记(1)基本环境

    1.pom引入 <dependencies> <dependency> <groupId>org.mybatis</groupId> <artif ...

  6. [Beta]the Agiles Scrum Meeting 8

    会议时间:2020.5.22 21:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 帮助解决博客评分功能遇到的问题 tq 暂无 wjx 完成批量创建团队项目功能 班级 ...

  7. echart3 力引导布局实现节点的提示和折叠

    最近在项目中需要开发一个图表来显示人员的各种属性,类似于一种树形的结构进行显示数据.如果多个人员有同一个属性,那么需要将相同的属性进行连线,即关联起来.即形成一个关系图,由于我自身对echarts稍微 ...

  8. Noip模拟4(忁靈霁) 2021.6.6

    T1 随(Rand) 由杠哥大定理可得,这题目前不可做,先跳走啦,咕咕.... T2 单(single) 考场上,简单看一眼就看出是个高斯消元,然后..... 板子没记住!!! 然而这不是最糟糕的.. ...

  9. 21.6.17 test

    \(NOI\) 模拟赛. \(T1\) 正解树形DP,由于不是很熟悉概率和期望所以打了个20pts暴力,说不定见多了概率能打出60pts半正解?最后的虚树更不会. \(T2\) 又是概率,还有坐标数量 ...

  10. IDA*、剪枝、较难搜索、扫描——DNA sequence HDU - 1560

    万恶之源 翻译 题意就是给出N个DNA序列,要求出一个包含这n个序列的最短序列是多长 这是一道搜索题,为什么呢?从样例可以感受到,我们应该从左往右"扫描",从n个DNA序列中取出某 ...