Golang 語言基礎之六: string, pointer

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

Golang 語言基礎之六: string, pointer

Golang 語言基礎系列:

  • Golang 語言基礎之一: type, variable, constant
  • Golang 語言基礎之二: for, ifelse, switch
  • Golang 語言基礎之三: array, slice
  • Golang 語言基礎之四: map, range
  • Golang 語言基礎之五: function
  • Golang 語言基礎之六: string, pointer
  • Golang 語言基礎之七: struct, method
  • Golang 語言基礎之八: interface
  • Golang 語言基礎之九: error, panic, recover
  • Golang 語言基礎之十: goroutine, channel

字串類型 string

字串在 Golang 源碼檔案 runtime.h 中的定義如下:

struct String{byte* str;intgo len;};

可以看出,其內部包含一個 byte 類型的數組,Golang 採用 UTF-8 編碼方式。和 C/C++ 的字元數組不同,Golang 的字元數組有下面的特點:

  • string 類型的零值為空白字串。
  • 不能用序號擷取位元組元素指標,&s[i] 為非法。
  • string 是不可變類型,其內部儲存資料的字元數組無法修改。如需修改,需要將 string 對象轉化為 rune 類型(如果字串含有非 ASIC 碼字元)或者 byte 類型(如果字串由 ASIC 碼字元組成)的 slice 對象。修改後的字元數組會重新分配記憶體儲存在一個新的字串對象中。
  • 位元組數組尾部不包含 \0

關於 string 的使用方法我們看個例子:

package mainimport "fmt"func main() {// 預設 string 類型對象零值為空白字串,尾部不包含 `\0`var emptyStr stringfmt.Println("emptyStr is: ", emptyStr)fmt.Println("len(emptyStr) is: ", len(emptyStr))// 聲明 string 對象並初始化,使用下標訪問。// 注意,如果字串中包含中文等非 ASIC 碼的字元,則使用下標索引會導致與期望不符的結果// 字串是 UTF-8 編碼,所以非 ASIC 碼字元不止一個位元組,而使用下標獲得的是每個位元組的內容。str := "I like 高圓圓"fmt.Println("string object is: ", str)fmt.Println("len(str) = : ", len(str))fmt.Println("str[1]: ", str[1])// 使用 ` 文法可以聲明無轉義的字串str = `ILoveGolang`fmt.Println("str: ", str)// 修改字串,注意將字串分別轉化為 `rune` 和 `byte` 的 `slice` 對象。// 它們的長度是不相等的,`rune` 切片對象的長度等於原始 `string` 對象中的字元個數。// `byte` 切片對象的長度等於原始 `string` 對象在記憶體中所佔的位元組數,其值和 `len` 取得的 `string` 對象長度相等// 如果 `string` 對象中有非 ASIC 碼,則兩者的長度是不相等的。// 所以為了保證相容性,最好將 `string` 對象轉化為 `rune` 切片對象後進行修改。str = "I like 高圓圓"fmt.Println("Before modification, str: ", str)fmt.Println("len(str) = : ", len(str))rune_str := []rune(str)byte_str := []byte(str)fmt.Println("len([]rune(str)) = ", len(rune_str))fmt.Println("len([]byte(str)) = ", len(byte_str))rune_str[7] = '範'rune_str[8] = '冰'rune_str[9] = '冰'fmt.Println("After modification, str:  ", string(rune_str))// 單引號中的字元常量為 `rune` 類型,取類型後為 int32v_char := 'g'fmt.Printf("The type of v_char is %T\n", v_char)}

將上面的代碼存入源檔案 string.go 並使用 go run string.go 可以看到下面的輸入:

emptyStr is:  len(emptyStr) is:  0string object is:  I like 高圓圓len(str) = :  16str[1]:  32str:  I      Love      GolangBefore modification, str:  I like 高圓圓len(str) = :  16len([]rune(str)) =  10len([]byte(str)) =  16After modification, str:   I like 範冰冰The type of v_char is int32

指標類型 pointer

Golang 中的指標和 C/C++ 相同的地方有:

  • 指標 *T
  • 指標的指標 **T
  • 通過 operator * 訪問指標指向的對象,& 取對象的地址

不同的地方有:

  • 指標的預設值為 nil,而不是 NULL
  • 指標不能進行加減運算,指標所指對象的成員使用 . 訪問而非 ->
  • 使用 unsafe.Pointer 可以對指向不同類型對象的指標進行轉換
  • 指標不能進行 +- 運算,以保證安全性。

使用執行個體如下:

package mainimport ("fmt""unsafe")func main() {// 檢查指標對象的零值為 nilvar p *intfmt.Println("The zero value of a pointer is: ", p)// 指向指標的指標pp := &pfmt.Printf("The type of a pointer points another pointer is: %T\n", pp)// 指標對象賦值intVar := 100000000p = &intVarfmt.Println("After assignment, p is: ", p)fmt.Println("The value pointer p points is: ", *p)// 使用 unsafe.Pointer 方法可以將一個類型的指標轉化為 Pointer// Pointer 可以被轉化為任意類型的指標。// 注意由於 int 為 int32 的別名,占 4 個位元組,所以我們將其轉化為含有 4 個位元組元素的 `byte` 數組指標var strP *[4]bytestrP = (*[4]byte)(unsafe.Pointer(p))fmt.Println("After \"(*[4]byte)(unsafe.Pointer(p))\", *[4]byte pointer strP is: ", strP)fmt.Println("After \"(*[4]byte)(unsafe.Pointer(p))\", *[4]byte pointer strP points to: ", *strP)// 指標指向的對象內容使用 `.` 而不是 `->` 來進行訪問type User struct {name string}userP := &User{"Xiaohui",}fmt.Println("Before change, The value userP points to is: ", *userP)userP.name = "Ross"fmt.Println("After change,  The value userP points to is: ", *userP)}

將上面的代碼存入源檔案 pointer.go 並使用 go run pointer.go 可以看到下面的輸入:

The zero value of a pointer is:  <nil>The type of a pointer points another pointer is: **intAfter assignment, p is:  0xc20800a240The value pointer p points is:  100000000After "(*[4]byte)(unsafe.Pointer(p))", *[4]byte pointer strP is:  &[0 225 245 5]After "(*[4]byte)(unsafe.Pointer(p))", *[4]byte pointer strP points to:  [0 225 245 5]Before change, The value userP points to is:  {Xiaohui}After change,  The value userP points to is:  {Ross}

關於 unsafe.Pointer,建議閱讀這篇文章,裡面做了很好的總結。

參考資料

  • The Go Programming Language
  • 學習 Go 語言 中文版
  • Go in Action 中文版
  • The way to Go 中文版
  • Go by Example
  • Organizing Go code
  • Testing Techniques
  • Go 語言分享
  • Go 學習筆記
  • Go 語言簡介
  • Tony Bai 的部落格

-- EOF --

  • Golang 語言基礎之五: function→
  • ← Golang 語言基礎之七: struct, method

聲明: 本文採用 BY-NC-SA 協議進行授權. 轉載請註明轉自: Golang 語言基礎之六: string, pointer

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.