go 语言程序设计—第2章—程序结构

2023-12-27 17:54:00

2.1 名称

如果一个实体在函数中声明,它只在函数局部有效。如果声明在函数外,它将对包里面所有源文件可见。
实体第一个字母的大小写决定其可见性是否跨包。如果名称以大写字母开头,它是导出的,意味着它对包内核包外是可见和可访问的。包名本身总是由小写字母组成。

2.2 声明

有4个主要的声明:变量(var), 常量(const), 类型(type)和函数(func)

2.3 变量

var name type = expression

2.3.1 短变量的声明

name := expression

短变量声明最少声明一个新变量
f, err := os.Open(infile)
//…
f, err := os.Create(outfile) // 编译错误:没有新的变量

2.3.2 指针

不是所有的值都有地址,但是所有的变量都有。

x := 1
p := &x
fmt.Println(*p) // “1”
*p = 2 // 等于 x=2
fmt.Println(x)

2.3.3 new 函数

表达式 new(T) 创建一个未命名的 T 类型变量,初始化为 T 类型的零值,并返回其地址。

p := new(int)

2.3.4 变量的生命周期

编译器可以选择使用堆和栈上的空间来分配内存,这个选择不是基于使用 var 或 new 关键字来声明变量。

2.4 赋值

2.4.1 多重赋值

x,y = y, x // 交换变量

f, err = os.Open(“foo.txt”)
v, ok = m[k] // map 查询
v, ok = x.(T) // 类型断言
v, ok = <- ch //通道接收

2.4.2 可赋值性

medals := []string{“gold”, “silver”, “bronze”}

可赋值性规则:类型必须精准匹配,nil 可以被赋给任何接口变量或引用类型。

两个值使用 == 和 != 进行比较与可赋值性相关:任何比较中,第一个操作数相对第二个操作数的类型必须是可赋值的,或者可以反过来赋值。

2.5 类型声明

type Celsius float64
type Fahrenheit float64
var c Celsius
var f Fahrenheit
fmt.Println(c == 0) // "true"
fmt.Println(f >= 0) // "true"
fmt.Println(c == f) // 编译错误: 类型不匹配
fmt.Println(c == Celsius(f)) // "true"

下面的声明中, Celsium 参数 c 出现在函数名字前面,名字叫 String 的方法关联到 Celsius 类型。

func (c Celsius) String() string { return fmt.Sprintf("%g Celsius", c)}

fmt.Println(c.String())

2.6 包和文件

每个包给它的声明提供独立的命名空间。

2.6.1 导入

导入不用的包会编译错误。

2.6.2 包初始化

包的初始化从初始化包级别的变量开始,这些变量按照声明顺序初始化,在依赖已解析完毕的情况下,根据依赖的顺序进行。

init 函数的机制。任意文件可以包含任意数量的声明如下的函数:
func init() {}
这个 init 函数不能被调用和被引用。如果p导入了包q,可以确保 q 在 p 之前已完全初始化,main 包最后初始化。

2.7 作用域

一个声明的词法块决定声明的作用域大小。像 int, len 和 true 等内置类型、函数或者常量在全局块中声明并且对整个程序可见。在包级别级的声明,可以被同一个包里的任何文件引用。导入的包是文件级别的,所以它们可以在同一个文件内引用,但是不能在没有另一个 import 的前提下被同一个包中其他文件引用。

不是所有的词法块都对应于显示大括号包围的语句序列,有一些词法块是隐式的。 for 循环创建了两个词法块:一个是循环本身的显式块,以及一个隐式块。隐式块包含初始化语句,判断条件,后置语句(i++).i++).

文章来源:https://blog.csdn.net/houzhizhen/article/details/135245951
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。