len
(以及cap
、close
、delete
和make
)函数调用的实参?T{...}
)表示?nil
标识符表示?()
中?
注意:此答案基于标准编译器的实现。事实上,函数类型的值是否有间接底层部分是难以证明的。 另外,字符串和接口类型的值在逻辑上应该被认为是不含间接底层部分。 请阅读值部一文获取更多信息。
len
(以及cap
、close
、delete
和make
)函数调用的实参?
len | cap | close | delete | make | |
---|---|---|---|---|---|
字符串值 | 可以 | ||||
数组或者数组指针值 | 可以 | 可以 | |||
切片值 | 可以 | 可以 | 可以 | ||
映射值 | 可以 | 可以 | 可以 | ||
通道值 | 可以 | 可以 | 可以 | 可以 |
可以被用做内置函数len
调用的参数的值的类型都可以被称为(广义上的)容器类型。
这些容器类型的值都可以跟在for-range
循环的range
关键字后。
类型 | 容器值是否支持添加新的元素? | 容器值中的元素是否可以被替换? | 容器值中的元素是否可寻址? | 访问容器值元素是否会更改容器长度? | 容器值是否可以有间接底层部分? |
---|---|---|---|---|---|
字符串 | 否 | 否 | 否 | 否 | 是(1) |
数组 | 否 | 是(2) | 是(2) | 否 | 否 |
切片 | 否(3) | 是 | 是 | 否 | 是 |
映射 | 是 | 是 | 否 | 否 | 是 |
通道 | 是(4) | 否 | 否 | 是 | 是 |
(1) 对于标准编译器和运行时来说。
(2) 对于可寻址的数组值来说。
(3) 一般说来,一个切片的长度只能通过将另外一个切片赋值给它来被整体替换修改,这里我们不视这种情况为“添加新的元素”。
其实,切片的长度也可以通过调用reflect.SetLen
来单独修改。增加切片的长度可以看作是一种变相的向切片添加元素。
但reflect.SetLen
函数的效率很低,因此很少使用。
(4) 对于带缓冲并且缓冲未满的通道来说。
T{...}
)表示?
下面在四种类型的值(除了切片和映射类型的零值)可以用组合字面量表示。
类型(T ) |
T{} 是类型T 的零值? |
---|---|
结构体类型 | 是 |
数组类型 | 是 |
切片类型 | 否 (零值用 nil 表示) |
映射类型 | 否 (零值用 nil 表示) |
详见值复制成本一文。
nil
标识符表示?
下面这些类型的零值可以用预声明的nil
标识符表示。
类型(T ) |
T(nil) 的尺寸 |
---|---|
指针 | 1 word |
切片 | 3 words |
映射 | 1 word |
通道 | 1 word |
函数 | 1 word |
接口 | 2 words |
上表列出的尺寸为标准编译器的结果。 一个word(原生字)在32位的架构中为4个字节,在64位的架构中为8个字节。 一个Go值的间接底层部分未统计在尺寸中。
一个类型的零值的尺寸和其它非零值的尺寸是一致的。
详见方法一文。
详见类型内嵌一文。
如果一个函数调用在编译时刻被估值,则估值结果为一个常量。
函数 | 返回类型 | 其调用是否总是在编译时刻估值? |
---|---|---|
unsafe.Sizeof | uintptr |
总是如此。
但是请注意,如果这样的一个函数调用的实参类型为一个类型参数,则此函数调用的结果将不被视为一个常量。 |
unsafe.Alignof | ||
unsafe.Offsetof | ||
len |
int |
否
Go语言白皮书中提到:
请注意,即使这样的一个函数调用在编译时刻被估值,如果函数调用的实参类型为一个类型参数,则此函数调用的结果将不被视为一个常量。 |
cap |
||
real |
默认类型为float64 (结果为类型不确定值) |
否
|
imag |
||
complex |
默认类型为complex128 (结果为类型不确定值) |
否
|
请阅读此条问答获取详情。
请阅读此条问答获取详情。
允许被声明却不使用? | |
---|---|
包引入 | 不允许 |
类型 | 允许 |
变量 | 包级全局变量允许,但局部变量不允许(对于官方标准编译器)。 |
常量 | 允许 |
函数 | 允许 |
跳转标签 | 不允许 |
()
中?
()
中:
函数是不能多个被一起声明在一对小括号()
中的。跳转标签也不能。
包引入必须被声明在其它种类的代码元素的声明之前。
函数必须声明在任何函数体之外。匿名函数可以定义在函数体内,但那不属于声明。
跳转标签必须声明在函数体内。
下列表达式的估值结果可以包含一个额外的可选的值:
语法 | 额外的可选的值(语法示例中的ok )的含义 |
舍弃额外的可选的值会对估值行为发生影响吗? | |
---|---|---|---|
映射元素访问 |
e, ok = aMap[key]
|
键值key 对应的条目是否存储在映射值中 |
否 |
数据接收 |
e, ok = <- aChannel
|
被接收到的值e 是否是在通道关闭之前发送的 |
否 |
类型断言 |
v, ok = anInterface.(T)
|
接口值的动态类型是否为类型T |
是 (当可选的值被舍弃并且断言失败的时候,将产生一个恐慌。) |
make(chan struct{}) <- struct{}{}
// 或者
make(chan<- struct{}) <- struct{}{}
<-make(chan struct{})
// 或者
<-make(<-chan struct{})
// 或者
for range make(<-chan struct{}) {}
chan struct{}(nil) <- struct{}{}
// 或者
<-chan struct{}(nil)
// 或者
for range chan struct{}(nil) {}
select
流程控制代码块。
select{}
详见字符串一文。
Go101.org网站内容包括Go编程各种相关知识(比如Go基础、Go优化、Go细节、Go实战、Go测验、Go工具等)。后续将不断有新的内容加入。敬请收藏关注期待。
本丛书微信公众号(联系方式一)名称为"Go 101"。二维码在网站首页。此公众号将时不时地发表一些Go语言相关的原创短文。各位如果感兴趣,可以搜索关注一下。
《Go语言101》系列丛书项目目前托管在Github上(联系方式二)。欢迎各位在此项目中通过提交bug和PR的方式来改进完善《Go语言101》丛书中的各篇文章。我们可以在项目目录下运行go run .
来浏览和确认各种改动。
本书的twitter帐号为@Golang_101(联系方式三)。玩推的Go友可以适当关注。
你或许对本书作者老貘开发的一些App感兴趣。
sync
标准库包sync/atomic
标准库包