Golang 知識點總結

617742071 7年前發布 | 10K 次閱讀 Go語言 Google Go/Golang開發

本文是由TapirLiu總結的Golang中的一些知識點,對于深入學習Golang很有幫助,所以我特意翻譯了一下。

各種類型復制的時候的花費

本節標題也可以叫做“各種類型的值的大小” (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)

可使用內建函數的類型 (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函數參數的類型也叫做容器類型。

內建容器類型的值比較

假定容器的值可尋址(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

組合類型T{...}的值比較

Type (T) T{}是類型T的零值?
struct Yes
array Yes
slice No (零值是nil)
map No (零值是nil)

零值是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

這些類型的零值的大小和上面類型的大小保持一致。

編譯時被執行的函數

如果函數在編譯時被執行,那么它的返回值是常量。

Function 返回值 編譯時便計算?
unsafe.Sizeof uintptr Yes, 總是
unsafe.Alignof
unsafe.Offsetof
len int 有時候是
Go 規范中講到 :
  • 如果s是字符串常量,則len(s)是常量.
  • 如果s是數組或者是數組指針,則len(s)是常量.
cap
real float64
(默認類型)
有時候是

Go 規范中講到 : 如果s是復數常量,則real(s)和imag(s)是常量.

imag
complex complex128
(默認類型)
有時候是

Go 規范中講到 : 如果sr和si都是常量,則complex(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值。

注意:盡管map、slice、function類型不支持直接比較,但是它們的值卻可以和nil直接比較。如果兩個接口的動態類型不能比較,運行時比較這兩個接口會panic,除非其中一個的動態值是untyped nil。

可命名的源代碼元素

下面的源代碼元素可以命名,名稱必須是 Identifier

  可以使用_做名稱?
package No
import Yes
type Yes
variable Yes
constant Yes
function Yes
label Yes

命名的源代碼元素可以使用()分組聲明

下面的類型可以使用()分組生命

  • import
  • type
  • variable
  • constant

函數和標簽(label)不能使用()分組聲明。

可以在函數內外聲明的源代碼元素

下面的類型可以聲明在函數內,也可以聲明在函數外:

  • type
  • variable
  • constant

import必須在其它元素的聲明的前面(package語句的后面)。

函數在其它函數的外面聲明。(譯者注:函數變量/匿名函數可以在函數內聲明)

標簽(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{}{}// ormake(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{}

連接字符串的幾種方法

下面幾種方法都可以連接字符串(譯者注:不考慮性能):

1、使用+連接字符串。如果連接的字符串少于6個,官方的編譯器會對此優化,所以通常使用+簡便而有效。

2、使用strings包中的 strings.Join 連接字符串。

3、使用fmt包中的fmt.Sprintf,fmt.Sprint和fmt.Sprintln連接字符串。這三個方法可以將任意的類型連接成字符串。fmt.Sprintln會在字符串之間加空格,在字符串尾部加新的換行符。如果兩個值中的至少一個不是字符串,fmt.Sprint會在它們之間加空格。

4、包bytes的Buffer類型(或者內建函數copy)可以用來構建 byte slice, byte slice可以方便地轉換成字符串。

 

來自:http://www.udpwork.com/item/16086.html

 

 本文由用戶 617742071 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!