您的位置:首页 > 编程语言

Go编程语言规范3-表达式

2013-04-05 15:54 260 查看

限定标识符

限定标识符为使用包名前缀限定的标识符。包名与标识符均不能为空白的。限定标识符用于访问另一个包中的标识符,它必须被导入。 标识符必须是已导出且在该包的包块中声明。

math.Sin	// 表示math包中的Sin函数

函数字面

函数字面可赋予一个变量或直接调用。

f := func(x, y int) int { return x + y }
func(ch chan int) { ch <- ACK }(replyChan)

闭包 的函数字面:它们可引用定义在外围函数中的变量。 那些变量共享于外围函数与函数字面之间,并且只要它们可访问就会继续存在。

选择器 .

对于不为包名的主表达式 x,选择器表达式为,

x.f


对于非接口类型
T
*T
的值
x
x.f
中的
f
表示在
T
中最浅深度的字段或方法。 若并非只有一个
f
,该选择者表达式即为非法的。

对于接口类型
I
的变量
x
x.f
表示赋予
x
的值的名为
f
的真实方法。若在
I
方法集中没有名为
f
的方法,该选择者即为非法的。

其它情况下,所有
x.f
均为非法的。

x
为指针或接口类型且值为
nil
,对
x.f
进行赋值、求值或调用会产生 运行时恐慌.

选择者会自动解引用指向结构的指针。 若 x 为指向结构的指针,x.y 即为 (*x).y 的缩写; 若字段 y 亦为指向结构的指针,x.y.z 即为 (*(*x).y).z 的缩写, 以此类推。 若 x 包含类型为 *A 的匿名字段,且 A 亦为结构类型, x.f 即为 (*x.A).f 的缩写。

p.z   // (*p).z
p.y   // ((*p).T1).y
p.x   // (*(*p).T0).x

p.M2()  // (*p).M2()
p.M1()  // ((*p).T1).M1()
p.M0()  // ((*p).T0).M0()

下标表达式

形式为:a[x]

切片

对于数组或字符串,若
0 <= 
low
<= [code]high
<= len(a)[/code] 下标
low
high
即在界内,否则即在
界外
。 对于切片,其上界为该切片的容量
cap(a)
而非长度。常量下标必为非负值, 且可表示为
int
类型的值。若其下标也为常量,它们必定满足
low <= high
。 若
a
nil
或其下标在运行时越界,就会引发一个运行时恐慌

a[low : high]

类型断言

对于接口类型的表达式 x 与类型 T,主表达式x.(T),注意x必须为接口类型

var x interface{} = 7  // x 拥有动态类型 int 与值 7
i := x.(int)           // i 拥有类型 int 与值 7

type I interface { m() }
var y I
s := y.(string)        // 非法:string 没有实现 I(缺少方法 m)
r := y.(io.Reader)     // r 拥有 类型 io.Reader 且 y 必须同时实现了 I 和 io.Reader

更确切地说,若
T
为非接口类型,
x.(T)
断言
x
的动态类型 与
T
相同。在此情况下,
T
必须实现
x
的(接口)类型,除非其类型断言由于无法为
x
存储类型为
T
的值而无效。若
T
为接口类型,
x.(T)
则断言
x
的动态类型实现了接口
T


若该类型断言成立,该表达式的值即为存储于
x
中的值,且其类型为
T
。若该类型断言不成立, 就会出现一个运行时恐慌。换句话说,即使
x
的动态类型只能在运行时可知,在正确的程序中,
x.(T)
的类型也可知为
T


若类型断言以

v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)

若该断言成立,该表达式返回值对 (x.(T), true);否则,该表达式返回 (Z, false), 其中 Z 为类型为 T 的零值。此种情况不会产生运行时恐慌。 类型断言在这种构造中,其行为类似于函数调用返回一个值与一个布尔值以表示成功。

比较操作符

在任何比较中,第一个操作数必须为可赋予第二个操作数的类型,反之亦然。

相等性操作符
==
!=
适用于可比较操作数。 顺序操作符
<
<=
>
>=
适用于有序的操作数。这些比较操作的关系和值定义如下:

布尔值之间可比较。若两个布尔值同为
true
或同为
false
,它们即为相等。

通常情况下,整数值之间可比较或排序。

根据 IEEE-754 标准的定义,浮点数值之间可比较或排序。

复数值之间可比较。对于两个复数值
u
v
, 若
real(u) == real(v)
imag(u) == imag(v)
,它们即为相等。

根据按字节词法,字符串值之间可比较或排序。

指针值之间可比较。若两个指针指向相同的值或其值同为
nil
,它们即为相等。 指向明显为零大小变量的指针可能相等也可能不相等。

信道值可比较。若两个信道值通过相同的
make
调用 (§创建切片、映射和信道)创建或同为
nil
值,它们即为相等。

接口值可比较。若两个接口值拥有相同的动态类型与相等的动态值,或同为
nil
值,它们即为相等。

当非接口类型
X
的值可比较且
X
实现了
T
时, 非接口类型
X
的值
x
与接口类型
T
的值
t
则可比较。 若
t
的动态类型与
X
相同且
t
动态值等于
x
,它们即为相等。

若两个结构值的所有字段可比较,它们即可比较。若其相应的非空白字段相等,它们即为相等。

若两个数组元素类型的值可比较,则数组值可比较。若其相应的元素相等,它们即为相等。

地址操作符

对于类型为 T 的操作数 x,地址操作符 &x 将生成一个类型为 *T 的指针指向 x。对于指针类型为 *T 的操作数 x,间接指针 *x 表示类型为 T 的值指向 x。若 x 为 nil, 尝试求值 *x 将会引发运行时恐慌。

&x
&a[f(2)]
&Point{2, 3}
*p
*pf(x)

接收操作符

v1 := <-ch
v2 = <-ch
f(<-ch)
<-strobe  // 在时钟脉冲和丢弃接收值之前等待

x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch

若接收的值由一次成功向信道发送的操作发出的,则 ok 的值为 true; 若接收的值是由于信道被关闭或为空而产生的零值,则为 false。

类型转换

类型转换是形式为 T(x) 的表达式,其中 T 为类型,而 x 是可转换为类型 T 的表达式。

若类型以操作符
*
<-
或关键字
func
开始则必须加上括号:

*Point(p)        // 等价于 *(Point(p))
(*Point)(p)      // p 被转换为 (*Point)
<-chan int(c)    // 等价于 <-(chan int(c))
(<-chan int)(c)  // c 被转换为 (<-chan int)
func()(x)        // 函数签名 func() x
(func())(x)      // x 被转换为 (func())
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: