Go语言学习笔记(一)程序结构

来源:互联网 发布:华方 线切割编程 编辑:程序博客网 时间:2024/05/21 08:39

-- 名称

有25个关键字,以前不常见的:chan,go,fallthrough

还有一些内置的预声明的常量、类型和函数

常量:

true,false,iota,nil

类型:

int,8/16/32/64, uiint,8/16/32/64/ uintptr

float32,float64,complex128,complex64

bool,byte,rune,string,error

函数:make,len,cap,new,append,copy,close,delete,complex,real,imag,panic,recover


如果一个实体声明在函数内部,就只能在函数内部可见。

如果声明在函数外部,在包的所有源文件中可见。实体第一个字母大写,表明其对其它包可见,否则不可见。

包名称本身由小写字母组成。


-- 声明

包级别的类型,变量,常量,函数的声明,不区分顺序。

局部变量的声明和初始化在函数执行期间进行,包级别的初始化在main开始之前进行。

-- 变量

var name type = expr,type和expr可以省略一个,但不能同时省略。

默认初始化为零值:

- 数字类型:0

- 布尔类型:false

- 字符串:""

- 接口和引用类型(slice, 指针,map,通道,函数):nil


短变量声明,只用在函数内部,用来声明和初始化局部变量。

name := expr

:= 表示声明,而 = 表示赋值。

:= 左侧必须有一个新变量,如果一些变量在同一个词法块中已经声明,那么就等同于赋值,外层的声明将被忽略。

例如:下面,i,k是声明和初始化局部新变量,j是赋值。

func ShortVar()

{

  var i = 0

  if i==0 {

    var j = 0

    i, j, k := 0, 0, 0

  }

}


-- 指针

变量是存储值的地方,指针的值是一个变量的地址。不是所有值都有地址,但每个变量都有。

函数返回局部变量的地址是非常安全的。变量的生命周期由其引用决定,不由其作用域决定。

返回局部变量的引用,表明局部变量从函数中逃逸,对于逃逸的变量,需要在堆上分配空间,否则,在栈上分配空间。


-- new(T)

创建一个未命名的T类型变量,返回其指针。


-- 多重赋值

在实际更新左侧的变量前,右侧所有的表达式被推演/计算。

对于返回多个变量的函数或者表达式,左侧变量个数需要一致,可以将不需要的使用空标识符。

_, err = io.Copy(dst, src),忽略字节数

一般布尔型用名称ok,error类型err

赋值的类型,必须精确匹配,nil可以被赋值给任何接口类型和引用类型。


-- 类型声明

type name underlying-type

T(x),将变量x转换为T类型的变量,不改变值,只改变类型。任何情况下,运行时的转换都不会失败。-- 什么意思?

不同命名类型的值不能直接比较。


-- 包

包类似于其它语言的模块,用于封装。包由若干个.go文件组成。go工具在调用编译器前将go文件排序。

包中的标识符,如果以大写字母开头,表明可以在其它包中访问。

包的初始化,按照包级别变量声明的顺序进行,依赖优先,比如:

var a = b + c // 最后把a初始化为3

var b = f()  // 调用f(),b初始化为2

var c = 1   // 首先c初始化为1

func f() int { return c+1 }

任何文件可以包含任意数量的init()函数,它不能被调用或者引用,按照它们声明的顺序执行。

func init() { /* ... */ }


在包级别,声明的顺序和作用域没有关系。所以,一个声明可以引用它自己或者它后面的其它声明。


再次强调,:=只能在func内起作用,必须有新变量,且如果同级别词法块中没有的变量就会作为新变量。即使外层有,会被屏蔽。比如

var cwd string

func init() {

  cwd, err := os.Getwd() // 由于包级别的cwd不在这个词法块中,因此这里新声明了一个cwd,使得外面的不可访问。

  if err != nil {

  }

}