初识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. MyBatis 中两表关联查询MYSQL (14)

    MyBatis 中两表关联查询MYSQL 1.创建数据库表语句 2.插入测试数据 3.pom文件内容 <?xml version="1.0" encoding="U ...

  2. NX Open 图层说

    我也是偶然发现的,在一次调试下,竟然会报警. 所以我写了测试代码,进行测试:结果如下 纳尼???还有271层?还能设置大于256层?NX open可以的.

  3. VMware虚拟机安装Linux

    我们都知道,Linux的学习如果依靠大量的物理真机,是不切实际的,会非常的麻烦. 今天来和分享一下VMware虚拟机安装Linux操作系统的方法 (centos  7) 1. 我们要先把VMware虚 ...

  4. the Agiles Scrum Meeting 3

    会议时间:2020.4.11 21:30 1.每个人的工作 今天已完成的工作 yjy:基本实现广播功能的前端 issues:小组任务1-增量开发组 wjx:基本实现注销功能的后端 issues:小组任 ...

  5. Less-5闯关失败

    进行第五关的通关还是用之前的方式进行测试以及判断是什么类型的注入.通过判断我们不难发现是字符型注入.但是出了问题,我们会发现按照原来的步骤进行注入都会返回"You are in " ...

  6. 高并发场景下JVM调优实践之路

    一.背景 2021年2月,收到反馈,视频APP某核心接口高峰期响应慢,影响用户体验. 通过监控发现,接口响应慢主要是P99耗时高引起的,怀疑与该服务的GC有关,该服务典型的一个实例GC表现如下图: 可 ...

  7. Java I/O框架 - 总结概述

    总结 以下需要重点掌握: 字节流,以下读取结束全部返回-1 字节节点流-访问文件 FileInputStream/FileOutputStream 可以读取任意文件 可以复制图片 读取字符String ...

  8. 如何使用python 新建文件夹以及递归创建文件夹

    转载:如何使用python 新建文件夹以及递归创建文件夹 | 酷python (coolpython.net) 1. os.mkdir 使用python创建文件夹,通常使用os.mkdir方法,在使用 ...

  9. linux 虚拟网络设备的使用

    1. linux 常见虚拟网络设备分类 常见虚拟网络设备有:bridge, tun/tap, veth-pairs, macvlan, macvtap等.有一篇博文写的挺好的,图文并茂:虚拟网络设备, ...

  10. anaconda无法launch应用(无法l打开任何应用)的问题解决 (点击应用无反应)

    遇到了anaconda 无法launch 任何应用. 重装也不行. 先说我最终的解决方法(在官方文档中找到): 1. 启动 anaconda prompt , 输入 conda remove anac ...