go 语言程序设计—第2章—程序结构
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++).
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!