各种类型复制的时候的花费
本节标题也可以叫做“各种类型的值的大小” (the sizes of values of all kinds of types),底层可被不同的值共享的数据的大小未被计算。
word
Type | Cost Of Value Copying (Value Size) |
---|---|
bool | 1 byte |
int8, uint8, byte | 1 byte |
int16, uint16 | 2 bytes |
int32, uint32, rune | 4 bytes |
int64, uint64 | 8 bytes |
int, uint, uintptr | 1 word |
string | 2 words |
pointer | 1 word |
slice | 3 words |
map | 1 word |
channel | 1 word |
function | 1 word |
interface | 2 words |
struct | the sum of sizes of all fields |
array | (element value size) * (array length) |
lencapclosedeletemake
len | cap | close | delete | make |
---|---|---|---|---|
string | Yes | |||
array (and array pointer) | Yes | Yes | ||
slice | Yes | Yes | Yes | |
map | Yes | Yes | Yes | |
channel | Yes | Yes | Yes | Yes |
range
len
内建容器类型的值比较
假定容器的值可寻址(addressable)。
Type | 是否可以增加新元素 | 元素可更新 | 元素可寻址 | 查找会更改容器的长度 | 底层元素可以共享 |
---|---|---|---|---|---|
string | No | No | No | No | Yes(1) |
array | No | Yes(2) | Yes(2) | No | No |
slice | No(3) | Yes | Yes | No | Yes |
map | Yes | Yes | No | No | Yes |
channel | Yes(4) | No | No | Yes | Yes |
reflect.SetLen
T{...}
TT{}Tnilnil
nil
Type (T) | Size Of T(nil) |
---|---|
pointer | 1 word |
slice | 3 words |
map | 1 word |
channel | 1 word |
function | 1 word |
interface | 2 words |
这些类型的零值的大小和上面类型的大小保持一致。
编译时被执行的函数
如果函数在编译时被执行,那么它的返回值是常量。
uintptruintptruintptrintlen(s)len(s)intlen(s)len(s)float64sreal(s)imag(s)float64sreal(s)imag(s)complex128srsicomplex(sr, si)
不能被寻址的值
下面的值不能被寻址(addresses):
- bytes in strings:字符串中的字节
- map elements:map中的元素
- dynamic values of interface values (exposed by type assertions):接口的动态值
- constant values:常量
- literal values:字面值
- package level functions:包级别的函数
- methods (used as function values):方法
- intermediate values:中间值
- function callings
- explicit value conversions
- all sorts of operations, except pointer dereference operations, but including:
- channel receive operations
- sub-string operations
- sub-slice operations
- addition, subtraction, multiplication, and division, etc.
&T{}tmp := T{}; (&tmp)&T{}T{}
下面的值可以寻址:
- variables
- fields of addressable structs
- elements of addressable arrays
- elements of any slices (whether the slices are addressable or not)
- pointer dereference operations
不支持比较的类型
下面的类型不支持直接比较:
- map
- slice
- function
- struct types containing incomparable fields
- array types with incomparable elements
这些不能直接比较的类型不能用做map的key值。
nil
可命名的源代码元素
下面的源代码元素可以命名,名称必须是 Identifier
_
()
()
- import
- type
- variable
- constant
()
可以在函数内外声明的源代码元素
下面的类型可以声明在函数内,也可以声明在函数外:
- type
- variable
- constant
importpackage
函数在其它函数的外面声明。(译者注:函数变量/匿名函数可以在函数内声明)
标签(label)必须声明在函数内。
可以返回一个可选bool返回值的表达式
下面的表达式可以返回一个可选的bool值:
可选的bool返回值的意义 | 忽略可选值会影响程序的行为? | |
---|---|---|
map element access | map中是否包含要 | No |
channel value receive | 在channel关闭前收到的值是否已发出 | No |
type assertion | 接口的动态类型是否符合asserted type | Yes |
(当可选值被忽略时,如果类型不match则会抛出panic)|
使用channel机制永远阻塞当前goroutine的方法
下面的方法都可以永远阻塞当前的goroutine:
1、receive from a channel which no values will be sent to
<-make(chan struct{})
// or
<-make(<-chan struct{})
2、send value to a channel which no ones will receive values from
make(chan struct{}) <- struct{}{}
// or
make(chan<- struct{}) <- struct{}{}
3、receive value from a nil channel
<-chan struct{}(nil)
4、send value to a nil channel
chan struct{}(nil) <- struct{}{}
5、use a bare select block
select{}
连接字符串的几种方法
下面几种方法都可以连接字符串(译者注:不考虑性能):
++stringsfmtfmt.Sprintffmt.Sprintfmt.Sprintlnfmt.Sprintlnfmt.SprintbytesBuffercopy