一:Go编程语言规范--块、声明、作用域

时间:2022-08-28 21:18:18

1.块

块为一对大括号括住的声明和语句。块 = "{" { 语句 ";" } "}" .

除显式源码块外,还有隐式块:

    1. 全域块 包含所有的Go源码文本。
    2. 每个都有包含其所有Go源码文本的 包块
    3. 每个文件都有包含其所有Go源码文本的 文件块
    4. 每个 iffor 和switch 语句都被视为处于其自身的隐式块中。
    5. 每个 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

已导出标识符

标识符可被 导出 以允许从另一个包访问。同时符合以下条件即为已导出标识符:

    1. 标识符名的第一个字符为Unicode大写字母(Unicode类别“Lu”);且
    2. 该标识符在包块中已声明或为字段名或 方法名

其它所有标识符均为未导出的。

关键字

以下为保留关键字,不能用作标识符。

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.声明和作用域

声明可将非空白标识符"_"绑定到一个常量、类型、变量、函数或包。 在程序中,每个标识符都必须被声明。

作用域 即为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。

作用域说明:

  1. 预声明标识符的作用域为全域块。
  2. 在*(即在任何函数之外)声明的表示常量、类型、变量或函数(而非方法)的标识符其作用域为该包块。
  3. 已导入包的包名作用域为包含该导入声明的文件块。
  4. 表示方法接收器、函数形参或返回值变量的标识符,其作用域为该函数体。
  5. 在函数中声明为常量或变量的标识符,其作用域始于该函数中具体常量实现或变量实现ShortVarDecl表示短变量声明)的结尾,止于最内部包含块的结尾。
  6. 在函数中声明为类型的标识符,其作用域始于该函数中具体类型实现的标识符,止于最内部包含块的结尾。

注意:

  • 同一标识符不能在同一中声明两次,且在文件与包块中不能同时声明。
  • 在块中声明的标识符可在其内部块中重新声明。 当其内部声明的标识符在作用域中时,即表示其实体在该内部声明中声明。
  • 包子句(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编程语言规范--块、声明、作用域的更多相关文章

  1. ES6块级作用域及新变量声明(let)

    很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域.用var声明的变量具有变量提升(declaration hoist ...

  2. 一个经典的js中关于块级作用域和声明提升的问题

    function functions(flag) { if (flag) { function getValue() { return 'a'; } } else { function getValu ...

  3. ES6 let const 声明变量 块级作用域

    ES6 中除了使用 var 定义变量,还有let.const,定义变量. function getValue(condition){ console.log(typeof value2); // un ...

  4. javascript中不存在块级作用域&comma;所以要小心使用在块级作用域中的函数声明所带来的作用域混乱&period;

    在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...

  5. 关于Javascript没有块级作用域和变量声明提升

    Javascript是没有块级作用域的,在语句块中声明的变量将成为语句块所在代码片段的局部变量.例如: if(true){ var x=3; } console.log(x); 结果输出3. 再如: ...

  6. ES6-let、const和块级作用域

    1.介绍 总的来说,ES6是在ES2015的基础上改变了一些书写方式,开放了更多API,这样做的目的最终还是为了贴合实际开发的需要.如果说一门编程语言的诞生是天才的构思和实现,那它的发展无疑就是不断填 ...

  7. 《浏览器工作原理与实践》&lt&semi;09&gt&semi;块级作用域:var缺陷以及为什么要引入let和const?

    在前面我们已经讲解了 JavaScript 中变量提升的相关内容,正是由于 JavaScript 存在变量提升这种特性,从而导致了很多与直觉不符的代码,这也是 JavaScript 的一个重要设计缺陷 ...

  8. ECMAScript概述及浅谈const&comma;let与块级作用域

    ECMAScript可以看作javascript的标准规范,实际上javascript是ECMAScript的一门脚本语言,ECMAScript只提供了最基本的语言JavaScript对ECMAScr ...

  9. JavaScript模仿块级作用域

    avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...

随机推荐

  1. OpenCV成长之路:图像直方图

    http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超 ...

  2. android MessageQueue入门

    接触安卓几年了.但是感觉一直不是很明白,东西太多了.反过来说就是自己太菜了.很多东西其实都是模凌两可,不熟悉,很多知识点都是知道一点,最多大家都这样用.没问题,事件长了也一直这样用的.但是有个问题,安 ...

  3. Sorting It All Out (拓扑排序&plus;floyd)

    An ascending sorted sequence of distinct values is one in which some form of a less-than operator is ...

  4. Echart横坐标时间轴滑动

    主要针对于dataZoom的使用,代码如下: option = { title: { text: '未来一周气温变化', subtext: '纯属虚构' }, tooltip: { trigger: ...

  5. Windows 10 MBR转GPT

    Windows 10的创意者更新中,新增了mbr2gpt命令行工具,只需简单几步快速搞定分区表的转换 语法 MBR2GPT /validate|convert [/disk:] [/logs:] [/ ...

  6. &lbrack;转&rsqb;MySQL函数大全 及用法示例

    原文地址:http://blog.sina.com.cn/s/blog_4586764e0100h5ct.html 1.字符串函数ascii(str)   返回字符串str的第一个字符的ascii值( ...

  7. Unity3D笔记 Collect

    一.输入轴 默认输入轴: Horizontal 和 Vertical被映射到w, a, s, d键和方向键 Fire1, Fire2, Fire3被分别映射到Ctrl,Option(Alt)和Comm ...

  8. ORACLE 11GR2 安装时配置了域,后期删除

    因为用了一个安全平台.此平台居然不支持oracle中的服务吗有"."而这个点就是因为当时安装oracle录入了域.原来以为是修改服务名.百多了很多,最后发现就是删除域即可 感谢此文 ...

  9. 【Angular JS】正确调用JQuery与Angular JS脚本 - 修复Warning&colon; Tired to load angular more than once

    自己正在做一个小网站,使用Angular JS + Express JS + Mongo DB,在开发过程中,遇到一些问题,所以整理出来.希望对大家都有帮助. 这是今天解决的一个问题,Angular ...

  10. 「BZOJ4029」&lbrack;HEOI2015&rsqb; 定价 贪心

    「BZOJ4029」[HEOI2015] 定价 2015年4月28日2,7490 Description 在市场上有很多商品的定价类似于 999 元.4999 元.8999 元这样.它们和 1000 ...