一、语法结构
golang源码采用UTF-8编码。空格包括:空白,tab,换行,回车。
- 标识符由字母和数字组成(外加'_'),字母和数字都是Unicode编码。
- 注释:
/* This is a comment; no nesting */
// So is this.
</div>
二、字面值(literals)类似C语言中的字面值,但数值不需要符号以及大小标志:
23
0x0FF
</div>
1.234e7类似C中的字符串,但字符串是Unicode/UTF-8编码的。同时,\xNN总是有2个数字;\012总是3;两个都是字节:
"\xFF" // 1 byte
"\u00FF" // 1 Unicode char, 2 bytes of UTF-8
</div>
原生字符串:`\n\.abc\t\` == "\\n\\.abc\\t\\"
三、语法概述
golang基本上就是类C的语法,但使用反转的类型和声明,并使用关键字作为每个声明的开头。
var a int
var b, c *int // 注意与C的不同
var d []int
type S struct { a, b int }
</div>
基本的控制结构也十分熟悉:
if a == b { return true } else { return false }
for i = 0; i < 10; i++ { … }
</div>
注意:没有圆括号,但需要大括号。
后续会有更多有关这方面的内容。
四、分号
分号作为语句终止符号,但:
- 如果前一个符号是语句的结尾,那词法分析程序将自动在行尾插入一个分号
- 注意:比JavaScript的规则更清晰和简单
因此,下面的程序不需要分号:
package main
const three = 3
var i int = three
func main() { fmt.Printf("%d\n", i) }
</div>
在实际中,Go源码在for和if子句之外几乎都没有用到分号。
五、数值类型
golang数值类型(numeric types)是原生内置的,也是为大家所熟知的:
int uint
int8 uint8 = byte
int16 uint16
int32 uint32 float32 complex64
int64 uint64 float64 complex128
</div>
还有uintptr,一个大小足够存储一个指针的数值。
这些都是互不相同的类型;int不等于是int32,即便是在一个32位的机器上。
没有隐式类型转换(不过不要恐慌)。
Bool
普通的布尔类型bool,取值true和false(预定义的常量)。
if语句等使用布尔表达式。
指针类型和整型不是布尔类型。
string
原生内置的string类型代表不可改变的字节数组,即文本。string类型是用长度定界的,而不是以结尾0终止的。
字符串字面值是string类型。
和整型一样不可改变。可重新赋值,但不能修改其值。
正如"3"总是3,"hello"也总是"hello"。
Go语言对字符串操作提供了良好的支持。
六、表达式(Expressions)
大多都是类C语言的操作符。
二元操作符:
优先级 操作符 备注
5 * / % << >> & &^ &^是位清理操作符
4 + – | ^ ^是异或(xor)
3 == != < <= > >=
2 &&
1 ||
一元操作符包括:& ! * + – ^(外加用于通信的<-)
一元操作符^是求补码/反码操作。
Go vs. C表达式
可以让C程序员惊喜的是:
更少的优先级层次(应该容易)。
^替代了~
++和–不再是表达式操作符(x++是一个语句,不是表达式;*p++是(*p)++,而不是*(p++))
&^是新操作符,在常量表达式中很有用
<<和>>等需要一个无符号的移位计数。
无惊喜的是:
赋值操作与所期望的一样:+= <<= &^=等
表达式总体看起来相似(下标、函数调用等)
例子:
+x
23 + 3*x[i]
x <= f()
^a >> b
f() || g()
x == y + 1 && <-ch > 0
x &^ 7 // x with the low 3 bits cleared
fmt.Printf("%5.2g\n", 2*math.Sin(PI/8))
7.234/x + 2.3i
"hello, " + "world" // concatenation
// no C-like "a" "b"
</div>
数值转型
将一个数值从一个类型转换为另一个类型称为一次转型,其语法形式有点类似函数调用:
uint8(intVar) //截断到相应的大小
int(float64Var) //片段截断
float64(intVar) //转为float64
</div>
一些涉及string类型的转型:
string(0×1234) // == "\u1234"
string(sliceOfBytes) // bytes -> bytes
string(sliceOfInts) // ints -> Unicode/UTF-8
[]byte("abc") // bytes -> bytes
[]int("日本語") // Unicode/UTF-8 -> ints
</div>
切片(slice)与数组相关,稍后会有更多相关内容。
七、常量
数值常量是"理想数":没有大小或标志,因此没有U、L或UL作结尾。
077 // 八进制
0xFEEDBEEEEEEEEEEEEEEEEEEEEF //十六进制
1 << 100
</div>
下面是整数和浮点数值,字面值的语法决定其类型:
1.234e5 // 浮点
1e2 // 浮点
3.2i // 浮点虚数
100 // 整数
</div>
常量表达式
浮点和整型常量可以任意组合,最终表达式的类型由常量的类型决定。操作自身也取决于类型。
2*3.14 // 浮点: 6.28
3./2 // 浮点:1.5
3/2 // 整型:1
3+2i // 复数:3.0 + 2.0i
// 高精度
const Ln2 = 0.69314718055994530941723212145817656807
const Log2E = 1/Ln2
</div>
数值的表示范围足够大(目前最大用102

