自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

String是一個(gè)奇怪的引用類(lèi)型

開(kāi)發(fā) 后端
string 被設(shè)計(jì)為不可變, 是因?yàn)?string在現(xiàn)代任何語(yǔ)言中,使用很頻繁:多個(gè)對(duì)象可能都是這個(gè)字符面值, 然后就設(shè)計(jì)一個(gè)Pool來(lái)存儲(chǔ)string。

[[402400]]

本文轉(zhuǎn)載自微信公眾號(hào)「精益碼農(nóng)」,作者小碼甲 。轉(zhuǎn)載本文請(qǐng)聯(lián)系精益碼農(nóng)公眾號(hào)。

開(kāi)局兩張圖,內(nèi)容全靠刷。

馬甲哥看到這樣的現(xiàn)象,一開(kāi)始還是有點(diǎn)懵逼。

這個(gè)例子,string是純粹的引用類(lèi)型,但是在函數(shù)傳值時(shí)類(lèi)似于值傳遞;我之前給前后示例的內(nèi)存變化圖吧:

根因就是大多數(shù)高級(jí)語(yǔ)言都把String設(shè)計(jì)成不可變的: 由一個(gè)字符串池管理字符串面值。

為什么被設(shè)計(jì)成不可變。

這個(gè)我還真的搜索了一下[1]:

總結(jié)起來(lái):

  • string 被設(shè)計(jì)為不可變, 是因?yàn)?string在現(xiàn)代任何語(yǔ)言中,使用很頻繁:多個(gè)對(duì)象可能都是這個(gè)字符面值, 然后就設(shè)計(jì)一個(gè)Pool來(lái)存儲(chǔ)string。

既然pool里面共享字符面值,修改的時(shí)候又不能影響到別人,那就只好重新拷貝產(chǎn)生新的字符面值。

  • 不可變資源消除了多線程中的資源競(jìng)爭(zhēng):對(duì)于文本的修改都會(huì)導(dǎo)致創(chuàng)建新空間,因此在多個(gè)線程同時(shí)訪問(wèn)文本無(wú)需設(shè)置鎖,這對(duì)高頻使用的String很友好。
  • 字符串不變性對(duì)于[在哈希表中使用字符串作為鍵]很友好,需要計(jì)算哈希值的對(duì)象必須是不可變的,以確保哈希值不變。

一個(gè)有意思的現(xiàn)象是:String雖然是引用類(lèi)型,字符串對(duì)比時(shí)卻表現(xiàn)的像值類(lèi)型

  1. string str1="FooFoo"
  2. string strFoo="Foo"
  3. string str2= strFoo + strFoo; 
  4. return str1 == str2;           //  返回true 

正因?yàn)镾tring不可變性 & Pool的機(jī)制,頻繁變更字符串,會(huì)在池中產(chǎn)生很多臨時(shí)的不用的字符串,所以我們有了優(yōu)化的套路:

StringBuilder

代表可變的字符串,一旦修改不會(huì)嘗試創(chuàng)建新對(duì)象,而是動(dòng)態(tài)擴(kuò)展內(nèi)存

  1. var ss = new StringBuilder("Hello ", 100);  // 初次字符容量100 
  2. ss.Append("www.cnblogs.com"); 
  3. Console.WriteLine(ss.ToString());  // ss打印結(jié)果為:222 

Span

Span該出圈了,

Span提供對(duì)內(nèi)存連續(xù)區(qū)域的類(lèi)型安全訪問(wèn),該內(nèi)存可以位于堆、堆棧、甚至是非托管內(nèi)存;

與String不可變性相關(guān)的是ReadOnlySpan(值類(lèi)型), 提供內(nèi)存數(shù)據(jù)的只讀視圖,每次切片不會(huì)產(chǎn)生新對(duì)象,而是在已存在的連續(xù)空間上創(chuàng)造新的視圖。

  1. var text = "https://www.cnblogs.com/JulianHuang/p/14817621.html"
  2. ReadOnlySpan<char> nameSpan = text.AsSpan(8, 15); 
  3. nameSpan = nameSpan.Slice(4,7); 
  4. Console.WriteLine(nameSpan.ToString()); 

總結(jié)輸出

今天從兩張?jiān)幃惖木幊虉D聊到了String的不可變性、內(nèi)存分布, 延伸談到了

String不可變性的設(shè)計(jì)設(shè)計(jì)考量(有先射箭再畫(huà)靶的嫌疑??)

針對(duì)頻繁修改的String如何做內(nèi)存優(yōu)化

不是自吹,文章內(nèi)容在業(yè)界相當(dāng)硬核(多次被各大佬/CSDN點(diǎn)贊/轉(zhuǎn)載),閱讀和關(guān)注不是目的,更希望得到更多的閱讀反饋,互相促進(jìn)認(rèn)知的提升(相當(dāng)真誠(chéng)??)。

參考資料

[1]這個(gè)我還真的搜索了一下: https://www.c-sharpcorner.com/UploadFile/230635/why-string-are-immutable-in-dotnet/

 

責(zé)任編輯:武曉燕 來(lái)源: 精益碼農(nóng)
相關(guān)推薦

2021-07-24 13:11:19

Redis數(shù)據(jù)技術(shù)

2009-08-27 16:39:26

C# String類(lèi)型

2022-05-09 10:47:08

登錄SpringSecurity

2022-08-11 12:28:09

For-elsePython

2021-08-11 07:53:22

Git rejecthint

2024-08-14 13:24:24

2022-02-12 22:16:53

TypeScript類(lèi)型字符串

2013-06-28 17:28:04

推送

2017-11-29 18:11:00

ERP管理數(shù)字化

2019-12-09 15:00:48

TomcatServlet容器

2016-12-15 08:54:52

線程sessionopenSession

2021-08-02 08:21:53

Python編程語(yǔ)言開(kāi)發(fā)

2020-04-20 09:02:33

函數(shù)RPCCPU

2022-03-07 05:53:41

線程CPU代碼

2021-08-27 07:47:06

引用類(lèi)型

2023-03-13 08:09:03

Protobuffeature分割

2023-04-18 08:14:27

ElixirRustWebRTC

2012-07-16 11:27:08

項(xiàng)目開(kāi)發(fā)

2012-07-16 09:41:59

項(xiàng)目
點(diǎn)贊
收藏

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