偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Golang 字符串切片與 Python 列表的不同

開發(fā) 前端
最近在粉絲交流群里面看到不少學(xué) Python 的同學(xué)都在學(xué)習(xí) Golang,那么今天我們來(lái)看一個(gè)非?;A(chǔ)的數(shù)據(jù)結(jié)構(gòu):Python中的列表和 Golang 中的切片(Slice)。

最近在粉絲交流群里面看到不少學(xué) Python 的同學(xué)都在學(xué)習(xí) Golang,那么今天我們來(lái)看一個(gè)非常基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu):Python中的列表和 Golang 中的切片(Slice)。

這兩個(gè)數(shù)據(jù)結(jié)構(gòu)從形式上來(lái)說,非常相似。我們今天來(lái)對(duì)比一個(gè)只包含字符串的列表和一個(gè)字符串切片。

[[401172]]

相同點(diǎn)

在 Python 里面,我們定義一個(gè)有初始值的字符串列表:

  1. a = ['kingname', 'pm', 'xxx'] 

在 Golang 里面,我們定義一個(gè)有初始值的字符串切片:

  1. := []string{"kingname", "pm", "xxx"} 

接下來(lái),我們分別往字符串列表和字符串切片末尾增加幾個(gè)元素:

  1. a.append("address") 
  2. a.append("shanghai") 

在 Golang 里面:

  1. a = append(a, "address") 
  2. a = append(a, "shanghai") 

我們也可以賦值給其他的變量,看看修改一個(gè),另一個(gè)是否會(huì)發(fā)生修改:

  1. b = a 
  2. a[0] = 'superman' 
  3. print(b) 

運(yùn)行效果如下圖所示:

我們?cè)賮?lái)看看在 Golang 的效果:

  1. :a 
  2. a[0] = "superman" 
  3. fmt.Println(b) 

運(yùn)行效果如下圖所示:

那么,我們是不是可以說,Golang 的切片就相當(dāng)于 Python 里面元素?cái)?shù)據(jù)類型相同的列表?

不同點(diǎn)

現(xiàn)在,我們?cè)偻斜砗妥址衅锩娓骷右粋€(gè)元素,來(lái)看看運(yùn)行效果:

在 Python 里面,運(yùn)行效果如下圖所示:

進(jìn)一步實(shí)驗(yàn)?zāi)銜?huì)發(fā)現(xiàn),a 和 b 兩個(gè)列表是完全一樣的,只要修改任何一個(gè)列表,另一個(gè)都會(huì)隨之發(fā)生變化。

但是 Golang 里面并不是這樣,如下圖所示:

你修改任何一個(gè)切片,另一個(gè)切片都不會(huì)改變。

看到這里,你可能會(huì)覺得 Golang 里面,是不是append添加新的數(shù)據(jù),每次都會(huì)生成新的切片,所以才導(dǎo)致添加數(shù)據(jù)以后兩個(gè)切片就不一樣了。

但實(shí)際上并不是這樣,我們用另外一種初始化切片的方式來(lái)做一個(gè)測(cè)試:

在這個(gè)例子里面,我生成了一個(gè)長(zhǎng)度為5,容量為20的字符串切片。根據(jù)第15-19行的運(yùn)行結(jié)果可以看到,此時(shí),無(wú)論是根據(jù)索引修改里面的元素,還是使用 append 添加新的元素,兩個(gè)切片的變化都相同。如果我們把切片的容量調(diào)小,調(diào)整到6,再看看效果:

從這里可以看到,b 跟著 a 變了半截。a 新增的test字符串同時(shí)也能在 b 里面找到。但是 a里面新增的abcde卻沒有出現(xiàn)在 b 中。并且對(duì)a[0]的修改,也沒有出現(xiàn)在 b 中。

原因

Golang 的切片之所以會(huì)出現(xiàn)這個(gè)現(xiàn)象,這需要從數(shù)組與切片的區(qū)別來(lái)說起。在 Golang 里面,字符串?dāng)?shù)組和字符串切片非常像,但他們有一個(gè)根本的區(qū)別,就是數(shù)組是需要一開始就聲明長(zhǎng)度的,并且不能擴(kuò)容。而切片不需要聲明長(zhǎng)度,所以:

  1. [5]string{"xx", "yy"}  // 這是長(zhǎng)度為5的字符串?dāng)?shù)組 
  2. []string{"xx", "yy"} // 字符串切片   

而切片底層依然是數(shù)組,切片有一個(gè)容量的概念,指的就是它底層的數(shù)組的長(zhǎng)度。如果切片中的數(shù)據(jù)數(shù)量等于了切片的容量,那么下一次再添加一個(gè)新的數(shù)據(jù)的時(shí)候,切片底層就會(huì)創(chuàng)建一個(gè)原來(lái)長(zhǎng)度2倍(數(shù)據(jù)量小于1024的時(shí)候是2倍,大于1024的時(shí)候是1.25倍)的數(shù)組,然后把已有數(shù)據(jù)按順序拷貝進(jìn)去,接著再插入新的數(shù)據(jù)。

所以,回到上面的代碼。當(dāng)我們使用a := make([]string, 5, 6)創(chuàng)建一個(gè)容量為6的字符串切片的時(shí)候,它底層會(huì)初始化一個(gè)長(zhǎng)度為6的字符串?dāng)?shù)組。當(dāng)代碼執(zhí)行到b := a[0: 6]的時(shí)候,雖然這里的 b 是另外一個(gè)切片,它跟 a 擁有不同的內(nèi)存地址,但他們共用了同一個(gè)底層數(shù)組。只要數(shù)據(jù)小于6,那么對(duì)其中一個(gè)切片的數(shù)據(jù)進(jìn)行修改,本質(zhì)上就是對(duì)它底層數(shù)組的修改,而另一個(gè)切片也使用這個(gè)數(shù)組,所以也能看到這個(gè)修改。

但是當(dāng)a數(shù)據(jù)容量超過6以后,a 切片底層會(huì)重新生成一個(gè)長(zhǎng)度為12的數(shù)組,并把原有的老數(shù)據(jù)都拷貝到新的數(shù)組里面,接下來(lái)的所有修改都是對(duì)這個(gè)新的數(shù)組進(jìn)行修改。而此時(shí) b 切片底層還是老的長(zhǎng)度為6的數(shù)組,所以此時(shí)對(duì) a 切片的修改就不會(huì)反映到 b 上面了。

 

責(zé)任編輯:趙寧寧 來(lái)源: 未聞Code
相關(guān)推薦

2021-10-31 23:01:50

語(yǔ)言拼接字符串

2010-03-16 17:14:19

Python字符串

2024-03-12 07:35:39

Python字符串列表

2021-04-01 15:02:56

Python循環(huán)編程

2022-11-10 07:43:45

2023-10-26 12:01:30

Golang字符串

2023-07-05 14:42:40

Python字符串

2013-06-24 15:16:29

Java字符串拼接

2009-12-18 09:52:40

Ruby字符串處理函數(shù)

2023-12-15 10:27:01

暴力匹配算法Python字符串

2009-11-25 09:13:41

PHP數(shù)組轉(zhuǎn)字符串PHP字符串轉(zhuǎn)數(shù)組

2023-08-26 20:21:58

字符KotlinJava

2021-08-20 06:58:31

C++Python函數(shù)

2010-09-09 11:48:00

SQL函數(shù)字符串

2010-03-09 16:16:55

Python字符串

2010-03-09 15:15:02

Python字符串類型

2010-11-26 13:40:58

MySQL空字符串

2023-12-11 15:18:03

C++字符串Unicode

2023-08-21 10:28:00

字符串字符Python

2024-08-16 22:00:38

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)