Golang 知識點總結

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

目錄 [−]

  1. 各種類型複製的時候的花費
  2. 可使用內建函數的類型 (len、cap、close、delete、make)
  3. 內建容器類型的值比較
  4. 組合類別型T{...}的值比較
  5. 零值是nil的類型
  6. 編譯時間被執行的函數
  7. 不能被定址的值
  8. 不支援比較的類型
  9. 可命名的原始碼元素
  10. 命名的原始碼元素可以使用 ()分組聲明
  11. 可以在函數內外聲明的原始碼元素
  12. 可以返回一個可選bool傳回值的運算式
  13. 使用channel機制永遠阻塞當前goroutine的方法
  14. 連接字串的幾種方法

原文: Golang Summaries by TapirLiu

本文是由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)

可使用內建函數的類型 (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
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

 

1

2

3

 

<-make(chan struct{}) 

// or

<-make(<-chan struct{})

2、send value to a channel which no ones will receive values from

 

1

2

3

 

make(chan struct{}) <- struct{}{}

// or

make(chan<- struct{}) <- struct{}{}

3、receive value from a nil channel

 

1

 

<-chan struct{}(nil)

4、send value to a nil channel

 

1

 

chan struct{}(nil) <- struct{}{}

5、use a bare select block

 

1

 

select{}

連接字串的幾種方法

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

1、使用+連接字串。如果串連的字串少於6個,官方的編譯器會對此最佳化,所以通常使用+簡便而有效。
2、使用strings包中的strings.Join連接字串。
3、使用fmt包中的fmt.Sprintffmt.Sprint 和 fmt.Sprintln連接字串。這三個方法可以將任意的類型串連成字串。fmt.Sprintln會在字串之間加空格,在字串尾部加新的分行符號。如果兩個值中的至少一個不是字串,fmt.Sprint會在它們之間加空格。
4、包bytesBuffer類型(或者內建函數copy)可以用來構建 byte slice, byte slice可以方便地轉換成字串。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.