Go语言程序结构之变量
初识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语言程序结构之变量的更多相关文章
- Objective-C 学习笔记(一) 语言程序结构
Objective-C语言程序结构 “Hello World”简单示例 #import <Foundation/Foundation.h> //预处理命令,它告诉Objective-C语言 ...
- 个人学习笔记:C语言程序结构
个人笔记:C语言程序 函数 语句 输入输出对象 标识符 关键字 函数 一个C语言源程序,是由一个或多个函数定义顺序组成的,其中必须有一个函数名为main的主函数.C语言源程序中的函数是指完成特定数据处 ...
- 【值得收藏】C语言入门基础知识大全!从C语言程序结构到删库跑路!
01 C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { ...
- C语言中结构体变量之间赋值
近期,我阅读了某新员工小刘写的C语言代码,发现其对结构体变量之间的赋值不是非常熟悉. 对于两个同样类型的结构体变量,他均採用的是逐个成员变量直接赋值的形式.例如以下的代码演示样例: 如上代码所看到的, ...
- C语言 指向结构体变量的指针
一个指向变量的指针表示的是占内存中起始位置 一个指向结构体的变量的指针表示的是这个结构体变量占内存中的起始位置,同样它也可以指向结构体变量数组 定义结构体变量的指针: //假设已有一个结构体名为Stu ...
- 【Go语言系列】2.3、Go语言基本程序结构:变量及常量
1.什么变量 变量来源于数学,从根本上说,变量相当于是对一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间. 1.1变量声明 Go 语言变 ...
- Go语言程序结构
注意:Go语言源码文件编码格式必须是 UTF-8 格式,否则会导致编译器出错. 1.语言变量 a) 指定变量类型,声明后若不赋值,使用默认值. var name string b) 根据值自行判定变量 ...
- C语言_结构体变量指针做函数参数的使用案例
# include <stdio.h> # include <stdlib.h> # include <string.h> # include <malloc ...
- Python的程序结构[3] -> 变量/Variable[0] -> 变量类型
变量类型 / Variable Type 在 Python 中,变量主要有以下几种,即全局变量,局部变量和内建变量, 全局变量 / Global Variable 通常定义于模块内部,大写变量名形式存 ...
随机推荐
- WPF之资源专题
1.一般程序的资源可以分为四个等级: 数据库中的数据相当于放在仓库里 资源文件里的数据相当于放在旅行箱里 WPF对象资源里的数据相当于携带在背包里 变量中的数据相当于拿在手里 2.资源的查找顺序是沿着 ...
- mysql创建用户及赋予某用户权限(附带基础查看表内容)
首先登陆mysql 一:show databases; 展示所有数据库(root用户下) 二:use xxx (数据库名)使用use选择数据库 三:show xxx 查看数据库中的表 四:des ...
- vector 删除和插入
删除 #include <iostream> #include <vector> using namespace std; int main() { vector<int ...
- windows10安装MySQL8.0.27
1.官网下载安装包:https://dev.mysql.com/downloads/mysql/ 2.将解压文件解压到你安装的目录:D:\mysql-8.0.27-winx64 注意:不要放在有中文名 ...
- 初探JavaScript PDF blob转换为Word docx方法
PDF转WORD为什么是历史难题 PDF 转Word 是一个非常非常普遍的需求,可谓人人忌危,为什么如此普遍的需求,却如此难行呢,还得看为什么会有这样的一个需求: PDF文档遵循iOS32000的规范 ...
- SpringBoot打包到docker(idea+传统方式)
作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 目录 1. 方式1.通过idea 远程发布 1.1 修改docker.service文件 1. 进入服务器 2. 修改ExecStart行为下面内容 ...
- ScatterLayout分散布局在kv中的引用
from kivy.uix.scatterlayout import ScatterLayout from kivy.app import App class ScatterLayoutWidget( ...
- MarkDown之Typora使用
Typora:所见即所得 常用快捷键 加粗:ctrl + B 标题:ctrl + 16,对于与16级标题 插入公式:ctrl + Shift + m 插入代码:ctrl + Shift + K 插入图 ...
- 基于websocket实现的一个简单的聊天室
本文是基于websocket写的一个简单的聊天室的例子,可以实现简单的群聊和私聊.是基于websocket的注解方式编写的.(有一个小的缺陷,如果用户名是中文,会乱码,不知如何处理,如有人知道,请告知 ...
- Python大数据应用
一.三国演义人物出场统计 先检查安装包 1.jieba库基本介绍 (1)jieba库概述 jieba是优秀的中文分词第三方库 中文文本需要通过分词获得单个的词语 jieba是优秀的中文分词第三方库,需 ...