一:Go编程语言规范--块、声明、作用域
1.块
块为一对大括号括住的声明和语句。块 = "{" { 语句 ";" } "}" .
除显式源码块外,还有隐式块:
- 全域块 包含所有的Go源码文本。
- 每个包都有包含其所有Go源码文本的 包块。
- 每个文件都有包含其所有Go源码文本的 文件块。
- 每个
if、for和switch语句都被视为处于其自身的隐式块中。 - 每个
switch或select语句中的子句其行为如同隐式块。
块可嵌套并会影响作用域。
2.标识符
标识符被用来命名程序实体,例如变量和类型。一个标识符由一个或多个字母和数字组成。 标识符的第一个字符必须是字母。
给定一个标识符集,若其中一个标识符不同于该集中的任一标识符,那么它就是唯一的。 若两个标识符拼写不同,或它们出现在不同的包中且未 导出,那么它们就是不同的。否则,它们就是相同的。
空白标识符
空白标识符 通过下划线字符 _ 表示, 它可像其它标识符一样用于声明,但该标识符不能传入一个新的绑定。
预声明标识符
在全局块中,以下标识符是隐式声明的:
类型:
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr
常量:
true false iota
零值:
nil
函数:
append cap close complex copy delete imag len
make new panic print println real recover
已导出标识符
标识符可被 导出 以允许从另一个包访问。同时符合以下条件即为已导出标识符:
其它所有标识符均为未导出的。
关键字
以下为保留关键字,不能用作标识符。
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
3.声明和作用域
声明可将非空白标识符"_"绑定到一个常量、类型、变量、函数或包。 在程序中,每个标识符都必须被声明。
作用域 即为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
作用域说明:
- 预声明标识符的作用域为全域块。
- 在顶级(即在任何函数之外)声明的表示常量、类型、变量或函数(而非方法)的标识符其作用域为该包块。
- 已导入包的包名作用域为包含该导入声明的文件块。
- 表示方法接收器、函数形参或返回值变量的标识符,其作用域为该函数体。
- 在函数中声明为常量或变量的标识符,其作用域始于该函数中具体常量实现或变量实现ShortVarDecl表示短变量声明)的结尾,止于最内部包含块的结尾。
- 在函数中声明为类型的标识符,其作用域始于该函数中具体类型实现的标识符,止于最内部包含块的结尾。
注意:
- 同一标识符不能在同一块中声明两次,且在文件与包块中不能同时声明。
- 在块中声明的标识符可在其内部块中重新声明。 当其内部声明的标识符在作用域中时,即表示其实体在该内部声明中声明。
- 包子句(package xxx)并非声明;包名不会出现在任何作用域中。 其目的是为了识别该文件是否属于相同的包并为导入声明指定默认包名。
标签作用域:
标签通过标签语句声明(标识符:语句),并用于 break、continue 和 goto 语句.例如:
L:
for i < n {
switch i {
case :
break L
}
}
定义不会使用的标签是非法的。与其它标识符相反,标签并不限定作用域且与非标签标识符并不冲突。 标签的作用域为除任何嵌套函数体外其声明的函数体。
4.各种声明
常量声明
const Pi float64 = 3.14159265358979323846
const zero = 0.0 // 无类型化浮点常量
const (
size int64 =
eof = - // 无类型化整数常量
)
const a, b, c = , , "foo" // a = 3, b = 4, c = "foo", 无类型化整数和字符串常量
const u, v float32 = , // u = 0.0, v = 3.0
iota
iota可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1
const ( // iota重置为0
c0 = iota // c0 == 0
c1 = iota // c1 == 1
c2 = iota // c2 == 2
) const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Partyday
numberOfDays // 该常量未导出
)
在表达式列表中,每个 iota 的值都相同,因为它只在每个常量实现后增量。
const (
bit0, mask0 = << iota, <<iota - // bit0 == 1, mask0 == 0
bit1, mask1 // bit1 == 2, mask1 == 1
_, _ // skips iota == 2
bit3, mask3 // bit3 == 8, mask3 == 7
)
类型声明
声明类型不继承任何方法绑定到现存类型, 但接口类型或复合类型元素的方法集保持不变:
// Mutex为带有Lock和Unlock两个方法的数据类型.
type Mutex struct { /* Mutex字段 */ }
func (m *Mutex) Lock() { /* Lock实现*/ }
func (m *Mutex) Unlock() { /* Unlock实现*/ } // NewMutex和Mutex拥有相同的组成,但它的方法集为空.
type NewMutex Mutex // PtrMutex的基础类型的方法集保持不变.
// 但PtrMutex的方法集为空.
type PtrMutex *Mutex // *PrintableMutex的方法集包含方法
// Lock和Unlock绑定至其匿名字段Mutex.
type PrintableMutex struct {
Mutex
} // MyBlock为与Block拥有相同方法集的接口类型.
type MyBlock Block
类型声明可用来定义不同的布尔值、数字或字符串类型并对其附上方法:
type TimeZone int const (
EST TimeZone = -( + iota)
CST
MST
PST
) func (tz TimeZone) String() string {
return fmt.Sprintf("GMT+%dh", tz)
}
变量声明
变量声明将一个标识符绑定至一个创建的变量并赋予其类型和可选的初始值。
若给定一个表达式列表,则变量通过按顺序将该表达式赋予该变量(§赋值)来初始化;所有表达式必须用尽且所有变量根据它们初始化。
否则,每个变量初始化为其 零值。若该类型已存在,每个变量都赋予该类型。
否则,该类型根据该表达式列表赋值。
若该类型不存在且其对应表达式计算结果为无类型化常量, 则该声明变量的类型由其赋值描述。
实现限制:若在函数体内声明不会使用的变量,编译器可能将其判定为非法
var i int
var U, V, W float64
var k =
var x, y float32 = -, -
var (
i int
u, v, s = 2.0, 3.0, "bar"
)
var re, im = complexSqrt(-)
var _, found = entries[name] // 映射检查;只与“found”有关
短变量声明
短变量声明只能出现在函数内部。在某些情况下,例如初始化 if、 for、或 switch 语句时,它们可用来声明局部临时变量
i, j := ,
f := func() int { return }
ch := make(chan int)
r, w := os.Pipe(fd) // os.Pipe() 返回两个值
_, y, _ := coord(p) // coord() 返回三个值;只与和y同位的值相关
不同于常规变量声明,在至少有一个非空白变量时,短变量声明可在相同块中,对原先声明的变量以相同的类型重声明。 因此,重声明只能出现在多变量短声明中。 重声明不能生成新的变量;它只能赋予新的值给原来的变量。
field1, offset := nextField(str, )
field2, offset := nextField(str, offset) // 重声明 offset 在同一个块中使用var 重复声明是非法的
a, a := , // 非法:重复声明了 a,或者若 a 在别处声明,但此处没有新的变量
函数声明
函数声明可省略函数体。这样的标识符为Go外部实现的函数提供签名,例如汇编例程。
func min(x int, y int) int {
if x < y {
return x
}
return y
}
func flushICache(begin, end uintptr) // 外部实现
方法声明
方法为带 接收者 的函数。方法声明将标识符,即 方法名 绑定至方法。 它也将该接收者的 基础类型 关联至该方法。
接收者类型必须为形式 T 或 *T,其中 T 为类型名。
由 T 表示的类型称为接收者的 基础类型; 它不能为指针或接口类型且必须在同一包中声明为方法。
若该接收器的值并未在该方法体中引用,其标识符可在声明中省略。这同样适用于一般函数或方法的形参。
func (p *Point) Length() float64 {
return math.Sqrt(p.x * p.x + p.y * p.y)
}
func (p *Point) Scale(factor float64) {
p.x *= factor
p.y *= factor
}
func (Point) Scale(factor float64) {
....
}
一:Go编程语言规范--块、声明、作用域的更多相关文章
- ES6块级作用域及新变量声明(let)
很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域.用var声明的变量具有变量提升(declaration hoist ...
- 一个经典的js中关于块级作用域和声明提升的问题
function functions(flag) { if (flag) { function getValue() { return 'a'; } } else { function getValu ...
- ES6 let const 声明变量 块级作用域
ES6 中除了使用 var 定义变量,还有let.const,定义变量. function getValue(condition){ console.log(typeof value2); // un ...
- javascript中不存在块级作用域,所以要小心使用在块级作用域中的函数声明所带来的作用域混乱.
在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...
- 关于Javascript没有块级作用域和变量声明提升
Javascript是没有块级作用域的,在语句块中声明的变量将成为语句块所在代码片段的局部变量.例如: if(true){ var x=3; } console.log(x); 结果输出3. 再如: ...
- ES6-let、const和块级作用域
1.介绍 总的来说,ES6是在ES2015的基础上改变了一些书写方式,开放了更多API,这样做的目的最终还是为了贴合实际开发的需要.如果说一门编程语言的诞生是天才的构思和实现,那它的发展无疑就是不断填 ...
- 《浏览器工作原理与实践》<09>块级作用域:var缺陷以及为什么要引入let和const?
在前面我们已经讲解了 JavaScript 中变量提升的相关内容,正是由于 JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷 ...
- ECMAScript概述及浅谈const,let与块级作用域
ECMAScript可以看作javascript的标准规范,实际上javascript是ECMAScript的一门脚本语言,ECMAScript只提供了最基本的语言JavaScript对ECMAScr ...
- JavaScript模仿块级作用域
avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...
随机推荐
- java 字符串zlib压缩/解压
今天在测公司的中间件时发现,增加netty自带的zlib codec压缩处理后,就报decompress failed, invalid head之类的异常.后来发现,直接用bytebuf处理报文体是 ...
- jQuery演示10种不同的切换图片列表动画效果
经常用到的图片插件演示jQuery十种不同的切换图片列表动画效果 在线演示 下载地址 实例代码 <!DOCTYPE html> <html lang="en" c ...
- knockout源码分析之computed(依赖属性)
一.序列图 二.主要代码文件 1.dependentObservable.js:主要包含ko.computed相关方法的处理2.dependencyDetection.js:主要包含依赖的监控上下文对 ...
- 类似 Dribbble 下载按钮的 SVG 弹性动画进度条
Codrops 发布了一个如何创建一个基于弹性效果的 SVG 加载进度条教程,基于 SVG 和 TweenMax 实现.按钮开始的时候是一个带有箭头的图标,一旦它被点击,动画成一个有趣的小金属丝和一个 ...
- go语言编辑器:liteide
LiteIDE is a simple, open source, cross-platform Go IDE. LiteIDE是一款开源.跨平台的轻量级Go语言集成开发环境(IDE). 项目地址:h ...
- 【移动适配】移动Web怎么做屏幕适配(一)
屏幕适配是一个很容易被忽略的问题,但对于精益求精的产品而言,是必不可少的.对于Web开发的求职者而言,也是一个必需要理解清楚的经典问题 首发于微信公众号(啃先生) 壹 | Fisrt 移动端适配的是 ...
- SAP用户权限解剖及自修改
通常BASIS会使用PFCG做权限管理,时你保存时会产生一个系统外的profile name,记得SU01时用户有profile 和role两栏位吗?它们的关系如何呢? 首先明白几个概念.1.acti ...
- Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer
Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer 1. Java NIO(New Input/Output)1 1.1. 变更通知(因为每个事件都需要一个监听者 ...
- 10个学习Android开发的网站推荐
1. Android Developers 作为一个Android开发者,官网的资料当然不可错过,从设计,培训,指南,文档,都不应该错过,在以后的学习过程中慢慢理解体会. 2. Android Gui ...
- android 切换fragment的两种方式
使用add方法切换时:载入Fragment1Fragment1 onCreateFragment1 onCreateViewFragment1 onStartFragment1 onResume用以下 ...