1. 程式人生 > 其它 >Go語言學習日誌之string字串

Go語言學習日誌之string字串

技術標籤:Go語言學習go語言

Go語言學習日誌之string字串

學習任何一門程式語言,再在自己能力範圍內去閱讀原始碼是非常必要的,下面就是我對Go中的字串型別的一些粗淺的理解。
先來看看官方是怎麼描述string的:

// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string

注意這句話:

Values of string type are immutable.

翻譯過來就是string型別的值是不可改變的。剛學Go的時候覺得它和C語言很像,而在我的印象中C和C++中的字串是可以改變的,本著科學嚴謹的態度我簡單寫了一段程式碼印證了我的想法:

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s="abc";
	printf("Unchanged s[1]:%c\n",s[1]);
	printf
("Unchanged s:%s\n",s.c_str()); s[1]='a'; printf("Changed s[1]:%c\n",s[1]); printf("Changed s:%s\n",s.c_str()); }

輸出結果如下:

Unchanged s[1]:b
Unchanged s:abc
Changed s[1]:a
Changed s:aac

--------------------------------
Process exited with return value 0
Press any key to continue
. . .

很明顯C++中的字串是可以改變值的。
而在Go語言中字串是不可變的,字串不可變可以保證執行緒安全,所有程序使用的都是隻讀物件,無須加鎖;再者,方便記憶體共享,而不必使用寫時複製等技術;字串 hash 值也只需要製作一份。先來看看Go語言中如何“改變”字串吧:

str := "I am a string"
strBytes := []byte(str)

通過將字串轉換為陣列進行修改,然後再將修改完後的陣列轉化為字串進行儲存。
將這一點弄清楚之後我又想到一個問題:在Go語言中字串是可以重新賦值的:

func main() {
	s1 :="I am String1"
	s2 :="I am String2"
	s1=s2
	fmt.Print(s1)
}

輸出的結果是:

I am String2
Process finished with exit code 0

此時我猜測,會不會是Go將s1的地址空間替換為s2的地址空間從而這兩者共享一個地址空間呢?

func main() {
	s1 :="I am String1"
	s2 :="I am String2"
	s1=s2
	fmt.Print(&s1==&s2)
}

輸出的結果是:

false
Process finished with exit code 0

這說明在將s2的值賦給s1之後這哥倆並沒有變成一家人而是仍然分房住,只不過將s2中的內容複製過去了而已。不放心,又試了一下s1的地址到底變沒變:

func main() {
	s1 :="I am String1"
	fmt.Print(&s1)
	s2 :="I am String2"
	s1=s2
	fmt.Print("\n")
	fmt.Print(&s1)
}

輸出的結果是:

0xc0000881e0
0xc0000881e0
Process finished with exit code 0

由此得知我上文的推測是正確的。
以上內容均為個人淺薄的理解,如有不當之處煩請各位大佬不吝賜教,批評指正,十分感謝!