GO的第一天,声明和变量

Mr_J · · 541 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

其实之前有自学过go的基础,但是时隔蛮久的,然后也没有去经常性的使用,现在重头开始学习啦

声明

声明语句定义了程序的各种实体对象以及部分或全部的属性。Go语言主要有四种类型的声明语句:变量(var)常量(const)类型(type)函数(func)实体对象的声明。
一个Go语言编写的程序对应一个或多个以.go为文件后缀名的源文件中。每个源文件编写顺序是

  • 说明该源文件是属于哪个包。
package main
  • 包声明语句之后是import语句导入依赖的其它包
import "fmt"
  • 然后是包一级的类型、变量、常量、函数的声明语句,包一级的各种类型的声明语句的顺序无关紧要
var x, y int
const pi = 3.14

func sayhi(){
    fmt.Println("Hello")
}

变量

var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:

var 变量名字 类型 = 表达式

其中“类型”或“= 表达式”两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量。

var x int = 1
var y = 2
var i, j, k int                 // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

简短变量声明

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导

i := 100

和var形式声明语句一样,简短变量声明语句也可以用来声明和初始化一组变量:

i, j := 0, 1

请记住“:=”是一个变量声明语句,而“=”是一个变量赋值操作。

如果重复使用简短变量声明定义一个变量,那这个变量的第二次声明就是赋值

in, err := os.Open(infile)
// 这里只声明了out一个变量,err进行了赋值操作
out, err := os.Create(outfile)

简短变量声明语句中必须至少要声明一个新的变量,下面的代码将不能编译通过:

f, err := os.Open(infile)
// ...
f, err := os.Create(outfile) // compile error: no new variables

解决的方法是第二个简短变量声明语句改用普通的多重赋值语句。

简短变量声明语句只有对已经在同级词法域声明过的变量才和赋值操作语句等价,如果变量是在外部词法域声明的,那么简短变量声明语句将会在当前词法域重新声明一个新的变量。

ps:简单来说就是,简短变量声明你就当做普通声明来用,但是一般都是用在函数体内,重复声明一个变量的时候注意细节

指针

想了很久,没办法用比较通俗易懂的说法来简述,如果你跟我一样会PHP,那你就把这个指针理解为PHP中的引用就行了,直接用代码展示吧

x := 1
p := &x         // p, of type *int, points to x
fmt.Println(*p) // "1"
*p = 2          // equivalent to x = 2
fmt.Println(x)  // "2"

如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是 *int ,指针被称之为“指向int类型的指针”。如果指针名字为p,那么可以说“p指针指向变量x”,或者说“p指针保存了x变量的内存地址”。同时 *p 表达式对应p指针指向的变量的值。一般 *p 表达式读取指针指向的变量的值,这里为int类型的值,同时因为 *p 对应一个变量,所以该表达式也可以出现在赋值语句的左边,表示更新指针所指向的变量的值。

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

任何类型的指针的零值都是nil。如果p指向某个有效变量,那么p != nil测试为真。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是 nil 时才相等。
简单的函数使用指针:

func incr(p *int) int {
    *p++ // 非常重要:只是增加p指向的变量的值,并不改变p指针!!!
    return *p
}

v := 1
incr(&v)              // side effect: v is now 2
fmt.Println(incr(&v)) // "3" (and v is 3)

new函数

另一个创建变量的方法是调用用内建的new函数。表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为*T。
用new创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外,我们还可以在表达式中使用new(T)。换言之,new函数类似是一种语法糖,而不是一个新的基础概念。
下面的两个newInt函数有着相同的行为:

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

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

变量的生命周期

变量的生命周期指的是在程序运行期间变量有效存在的时间间隔。对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。而相比之下,局部变量的声明周期则是动态的:每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。

参考

《GO语言圣经》


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:Mr_J

查看原文:GO的第一天,声明和变量

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

541 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传