[译]Golang 知识点总结
Posted GoCN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[译]Golang 知识点总结相关的知识,希望对你有一定的参考价值。
本文转载自:http://colobu.com/2017/02/01/golang-summaries/
原文: by ima
本文是由TapirLiu总结的Golang中的一些知识点,对于深入学习Golang很有帮助,所以我特意翻译了一下。
1. 各种类型复制的时候的花费
本节标题也可以叫做“各种类型的值的大小” (the sizes of values of all kinds of types),底层可被不同的值共享的数据的大小未被计算。
下面的表格中一个 word
在32bit操作系统中代表4个字节,在64bit操作系统中代表8个字节,内容基于官方的Go 1.7的编译器。
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) |
2. 可使用内建函数的类型 (len
、cap
、close
、delete
、make
)
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
函数参数的类型也叫做容器类型。
3. 内建容器类型的值比较
假定容器的值可寻址(addressable)。
Type | 长度可变 | 元素可更新 | 元素可寻址 | 查找会更改容器的长度 | 底层元素可以共享 |
---|---|---|---|---|---|
string | No | No | No | No | Yes |
array | No | Yes | Yes | No | No |
slice | No | Yes | Yes | No | Yes |
map | Yes | Yes | No | No | Yes |
channel | Yes | No | No | Yes | Yes |
4. 组合类型T{...}
的值比较
Type (T ) |
T{} 是类型T 的零值? |
---|---|
struct | Yes |
array | Yes |
slice | No (零值是 nil ) |
map | No (零值是 nil ) |
5. 零值是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 |
这些类型的零值的大小和上面类型的大小保持一致。
6. 编译时被执行的函数
如果函数在编译时被执行,那么它的返回值是常量。
Function | 返回值 | 编译时便计算? |
---|---|---|
unsafe.Sizeof | uintptr |
Yes, 总是 |
unsafe.Alignof | ||
unsafe.Offsetof | ||
len | int |
有时候是 : 如果s是字符串常量,则 如果s是数组或者是数组指针,则 |
cap | ||
real | float64 (默认类型) |
有时候是 : 如果 |
imag | ||
complex | complex128 (默认类型) |
有时候是 : 如果 |
7. 不能被寻址的值
下面的值不能被寻址(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:中间值
channel receive operations
sub-string operations
sub-slice operations
addition, subtraction, multiplication, and division, etc.
function callings
explicit value conversions
all sorts of operations, except pointer dereference operations, but including:
注意, &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
8. 不支持比较的类型
下面的类型不支持直接比较:
map
slice
function
struct types containing incomparable fields
array types with incomparable elements
这些不能直接比较的类型不能用做map的key值。
注意:尽管map、slice、function类型不支持直接比较,但是它们的值却可以和nil
直接比较。如果两个接口的动态类型不能比较,运行时比较这两个接口会panic,除非其中一个的动态值是untyped nil。
9. 可命名的源代码元素
下面的源代码元素可以命名,名称必须是
可以使用 _ 做名称? |
|
---|---|
package | No |
import | Yes |
type | Yes |
variable | Yes |
constant | Yes |
function | Yes |
label | Yes |
10. 命名的源代码元素可以使用 ()
分组声明
下面的类型可以使用()
分组生命
import
type
variable
constant
函数和标签(label)不能使用()
分组声明。
11. 可以在函数内外声明的源代码元素
下面的类型可以声明在函数内,也可以声明在函数外:
type
variable
constant
import
必须在其它元素的声明的前面(package
语句的后面)。
函数在其它函数的外面声明。(译者注:函数变量/匿名函数可以在函数内声明)
标签(label)必须声明在函数内。
12. 可以返回一个可选bool返回值的表达式
下面的表达式可以返回一个可选的bool值:
可选的bool返回值的意义 | 忽略可选值会影响程序的行为? | |
---|---|---|
map element access | map中是否包含要 | No |
channel value receive | 在channel关闭前收到的值是否已发出 | No |
type assertion | 接口的动态类型是否符合asserted type | Yes |
(当可选值被忽略时,如果类型不match则会抛出panic)|
13. 使用channel机制永远阻塞当前goroutine的方法
下面的方法都可以永远阻塞当前的goroutine:
1、receive from a channel which no values will be sent to
|
2、send value to a channel which no ones will receive values from
|
3、receive value from a nil channel
|
4、send value to a nil channel
|
5、use a bare select block
|
14. 连接字符串的几种方法
下面几种方法都可以连接字符串(译者注:不考虑性能):
1、使用+
连接字符串。如果连接的字符串少于6个,官方的编译器会对此优化,所以通常使用+
简便而有效。
2、使用strings
包中的连接字符串。
3、使用fmt
包中的fmt.Sprintf
, fmt.Sprint
和 fmt.Sprintln
连接字符串。这三个方法可以将任意的类型连接成字符串。fmt.Sprintln
会在字符串之间加空格,在字符串尾部加新的换行符。如果两个值中的至少一个不是字符串,fmt.Sprint
会在它们之间加空格。
4、包bytes
的Buffer
类型(或者内建函数copy
)可以用来构建 byte slice, byte slice可以方便地转换成字符串。
GopherChina 是中国的最权威和最实力干货的Go大会,我们致力于为中国广大的Gopher提供最好的大会,我们本着非盈利目的来举办大会,前面两届大会在上海和北京都获得了非常好的口碑,今年我们大会将在四月份举办大会。举办Gopher大会,主要是汇集Gopher的广大开发者,聚集一批大规模应用Go的示范企业给大家分享,呈现一场cool的盛会。
以上是关于[译]Golang 知识点总结的主要内容,如果未能解决你的问题,请参考以下文章