首先說一下go中的字符串類型:
創新互聯主要從事成都做網站、成都網站建設、網頁設計、企業做網站、公司建網站等業務。立足成都服務興縣,10多年網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:18980820575
字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個字節連接起來的。Go語言的字符串的字節使用UTF-8編碼標識Unicode文本。
下面介紹字符串的三種遍歷方式,根據實際情況選擇即可。
該遍歷方式==缺點==:遍歷是按照字節遍歷,因此如果有中文等非英文字符,就會出現亂碼,比如要遍歷"abc北京"這個字符串,效果如下:
可見這不是我們想要的效果,根據utf-8中文編碼規則,我們要str[3]str[4]str[5]三個字節合起來組成“北”字及 str[6]str[7]str[8]合起來組成“京”字。由此引出下面第二種遍歷方法。
該方式是按照字符遍歷的,所以不會出現亂碼,如下:
運行結果:
從圖中可以看到第二個漢子“京”的開始下標是6,直接跳過了4和5,可見確實依照utf8編碼方式將三個字節組合成了一個漢字,str[3]-str[5]組合成“北”字,str[6]-str[8]組合成了“京”字。
由于下標的不確定性,所以引出了下面的遍歷方式。
1 可以先將字符串轉成 []rune 切片
2 再用常規方法進行遍歷
運行效果:
由此可見下標是按1遞增的,沒有產生跳躍現象。
操作字符串離不開字符串的拼接,但是Go中string是只讀類型,大量字符串的拼接會造成性能問題。
拼接字符串,無外乎四種方式,采用“+”,“fmt.Sprintf()”,"bytes.Buffer","strings.Builder"
上面我們創建10萬字符串拼接的測試,可以發現"bytes.Buffer","strings.Builder"的性能最好,約是“+”的1000倍級別。
這是由于string是不可修改的,所以在使用“+”進行拼接字符串,每次都會產生申請空間,拼接,復制等操作,數據量大的情況下非常消耗資源和性能。而采用Buffer等方式,都是預先計算拼接字符串數組的總長度(如果可以知道長度),申請空間,底層是slice數組,可以以append的形式向后進行追加。最后在轉換為字符串。這申請了不斷申請空間的操作,也減少了空間的使用和拷貝的次數,自然性能也高不少。
bytes.buffer是一個緩沖byte類型的緩沖器存放著都是byte
是一個變長的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一個 空的 buffer,但是可以使用,底層就是一個 []byte, 字節切片。
向Buffer中寫數據,可以看出Buffer中有個Grow函數用于對切片進行擴容。
從Buffer中讀取數據
strings.Builder的方法和bytes.Buffer的方法的命名幾乎一致。
但實現并不一致,Builder的Write方法直接將字符拼接slice數組后。
其沒有提供read方法,但提供了strings.Reader方式
Reader 結構:
Buffer:
Builder:
可以看出Buffer和Builder底層都是采用[]byte數組進行裝載數據。
先來說說Buffer:
創建好Buffer是一個empty的,off 用于指向讀寫的尾部。
在寫的時候,先判斷當前寫入字符串長度是否大于Buffer的容量,如果大于就調用grow進行擴容,擴容申請的長度為當前寫入字符串的長度。如果當前寫入字符串長度小于最小字節長度64,直接創建64長度的[]byte數組。如果申請的長度小于二分之一總容量減去當前字符總長度,說明存在很大一部分被使用但已讀,可以將未讀的數據滑動到數組頭。如果容量不足,擴展2*c + n 。
其String()方法就是將字節數組強轉為string
Builder是如何實現的。
Builder采用append的方式向字節數組后添加字符串。
從上面可以看出,[]byte的內存大小也是以倍數進行申請的,初始大小為 0,第一次為大于當前申請的最大 2 的指數,不夠進行翻倍.
可以看出如果舊容量小于1024進行翻倍,否則擴展四分之一。(2048 byte 后,申請策略的調整)。
其次String()方法與Buffer的string方法也有明顯區別。Buffer的string是一種強轉,我們知道在強轉的時候是需要進行申請空間,并拷貝的。而Builder只是指針的轉換。
這里我們解析一下 *(*string)(unsafe.Pointer(b.buf)) 這個語句的意思。
先來了解下unsafe.Pointer 的用法。
也就是說,unsafe.Pointer 可以轉換為任意類型,那么意味著,通過unsafe.Pointer媒介,程序繞過類型系統,進行地址轉換而不是拷貝。
即*A = Pointer = *B
就像上面例子一樣,將字節數組轉為unsafe.Pointer類型,再轉為string類型,s和b中內容一樣,修改b,s也變了,說明b和s是同一個地址。但是對s重新賦值后,意味著s的地址指向了“WORLD”,它們所使用的內存空間不同了,所以s改變后,b并不會改變。
所以他們的區別就在于 bytes.Buffer 是重新申請了一塊空間,存放生成的string變量, 而strings.Builder直接將底層的[]byte轉換成了string類型返回了回來,去掉了申請空間的操作。
Go中的binary包實現了簡單的數字與字節序列的轉換以及變長值的編解碼
package main
import ( "fmt" "bytes" "encoding/binary" ) func main(){ n := 0x12345678 bytesBuffer := bytes.NewBuffer([]byte{}) //BigEndian 大端順序存儲 LittleEndian小端順序存儲 binary.Write(bytesBuffer, binary.BigEndian, int32(n)) data:=bytesBuffer.Bytes() fmt.Printf("[0]: %#x addr:%#x\n",data[0],data[0]) fmt.Printf("[0]: %#x addr:%#x\n",data[1],data[1]) fmt.Printf("[0]: %#x addr:%#x\n",data[2],data[2]) fmt.Printf("[0]: %#x addr:%#x\n",data[3],data[3]) }
輸出
[0]: 0x12 addr:0xc042010248 [1]: 0x34 addr:0xc042010249 [2]: 0x56 addr:0xc04201024a [3]: 0x78 addr:0xc04201024b
也可以使用下面的方式
n := 0x12345678 var data []byte = make([]byte,4) //操作的都是無符號整型 binary.BigEndian.PutUint32(data,uint32(n))
可以使用下面的方式判斷當前系統的字節序類型
const INT_SIZE int = int(unsafe.Sizeof(0))
//判斷我們系統中的字節序類型 func systemEdian() { var i int = 0x1 bs := (*[INT_SIZE]byte)(unsafe.Pointer(i)) if bs[0] == 0 { fmt.Println("system edian is little endian") } else { fmt.Println("system edian is big endian") } }
現代化編程應該是:不強制用相同的 IDE,統一的代碼風格,方便的依賴管理,持續集成,版本控制等。
在我的青少年時期,我涉獵了編程基礎和一些匯編。當我學習了 Turbo Pascal 之后這事更進了一步,它提供了一種最早期的集成開發環境(IDE)。我覺得這下合我心意了。實際上,IDE 是一種讓你在一個友好的環境內,方便地編寫、編譯、調試和運行代碼的程序。Turbo Pascal 沒有太多的圖形界面(它基于文本),但它有菜單和窗口。你可以進入調試模式,跟蹤變量的值等等。
然后我轉到了 Delphi (一種圖形化的 Turbo Pascal),它擁有到今天看來仍然不錯的出色 IDE。我用 Visual Basic 設計了一個“會報時的鐘”,當時發表在 Bulletin Board Systems(使用 Windows 3.1 的一個系統)。那之后我發現了 Visual Studio。有好幾年我的 C++ 編程都是借用的 Visual Studio。以上就是我一直使用的所有 IDE。
早在八十年代初,Smalltalk 就有了著名的強大圖形化 IDE(Youtube 視頻)。
我認為,使用 IDE 并不代表著“現代化”。現在的 IDE 和過去的 IDE 非常相像。雖然我們編程的內容改變了,但在很多情況下,我們如何編程卻沒有改變。在我的 Dell 筆記本電腦里裝著最新版 Visual Studio。換做 20 年前的我,也能完美地輕松上手它。調試、代碼補全、遠程代碼執行,它和以前很像。事實上,Visual Studio 從未與 Turbo Pascal 相差很大過。而我發現這非常令人沮喪。我以為我們應該取得比這更快的進步。
我提出了現代化編程在桌面外觀上難有作為的觀點。圖形化用戶界面(GUI)只是表層。現代化編程技術都是關于流程和實際工具的,而不是它們之上的表層。我不在乎你是否使用 Eclipse 或 Emacs,這和你如何現代化毫不相關。
那么,什么是“現代化”?
編碼是社會化的
在 20 年前,要求你公司里的每個人都使用相同的 IDE,并且要唯一依賴于這種 IDE 來構建、測試和部署代碼,這是很明智的。但在你公司外有很多聰明的人,他們往往不使用你這種 IDE。如今,你可以觸及他們了。這意味著對于所采用的工具和流程你必須明智。
如果你嘲弄使用 Atom 文本編輯器、Visual Studio 或者 Emacs 編程的人,那你就不是社會化的。你需要盡可能的包容,否則就會付出代價。
Go 語言有自己的格式化工具
我不在乎在你保存的時候,是不是自動重新格式化代碼,或者有沒有點擊重新格式化按鈕,或者是不是輸入 go fmt,這些都一樣。但它無疑是一個卓越的現代化的想法。這就是進步。所有的編程語言都應該為用戶強加一個唯一的代碼格式。別再 bikeshedding(過于關心旁枝末節,而忽視主要問題)。
我們很清楚 Java 擁有規范,但規范是不夠的。我們需要一個工具,能把代碼作為輸入,并生成一個唯一定義了的輸出,它能處理從行長度到空格的所有問題。
這個工具的目標是對于應該如何格式化代碼,不再有任何可能有的爭議,而且產生正確的格式不費吹灰之力。我簡直無法告訴你這是多么的重要。
像 Rust、Go、Swift 這樣的編程語言有自己的程序包管理系統
因此,例如在 Swift 中,我可以創建一個名為 Package.swift 的小文本文件,并把它放入我項目的根文件,在那里聲明我的依賴。
importPackageDescription
letpackage = Package(
name: "SwiftBitsetBenchmark",
dependencies: [
.Package(url: "",
majorVersion: 0),
.Package(url: "",
majorVersion: 0)
]
)
然后我可以輸入 swift build,軟件會自動抓取依賴代碼,并構建我的程序。這在 Swift 運行的所有地方通用。你使用哪種文本編輯器和 IDE 都沒關系。
你不想使用文本編輯器,而更喜歡圖形界面?可以。都沒有區別。
為什么那樣顯得現代化?因為自動地解決依賴關系而不費吹灰之力,對于 20 年前的我來說就像魔術。并且自動地、系統地解決依賴關系是極其重要的。我不想永遠都不得不手動安裝和部署一個依賴項。我希望其他人能夠在幾秒內把我的庫添加到他們項目中,而不是幾分鐘或是幾小時。
是的,你可以將它添加到現有的語言(如:Java 的 Maven 或是 IED)但需要有一個唯一的方法讓它起效。
像 Rust、Go、Swift 這樣的編程語言,在一開始就支持單元測試。
比如在 Go 里,創建一個 filemyproject_test.go,然后添加 func TestMyStuff(t * testing.T)這樣的函數,然后輸入 go test 既可。
在 20 年前,幾乎沒有人測試他們的代碼,而今天已經是一個必要要求,您和它需要以一種唯一的方式來做,這樣你就可以在項目之間移動,還總是知道如何測試了。
如果不能在你的代碼中立刻認出健全的單元測試,我會設想你的代碼嚴重損壞了。
持續集成
代碼更改時,你想要一個遠程工具來獲取新代碼,并測試它,以便可以提前停止回歸。人們可以在你的代碼上運行測試還不夠,他們還需要看到自動化測試的結果,自行檢查最終的故障。
持續集成是較大規模計劃的一部分:你必須在你編程的時候瘋狂地自動化程序。體力勞動應該最小化。有時候這意味著你真的應該只是點擊一個按鈕,無論是通過一個圖形化用戶界面,還是命令窗口,但它不意味著需要反復地遵循一系列復雜的命令。
版本控制
20 年前,你在桌面上編寫代碼,并通過電子郵件發送新代碼(作為補丁)是講得通的。但這只在緩慢的合作節奏中有意義。如今,這么做是愚蠢的。任何差于 Git 的都是落后的。注意,如今甚至微軟構建 Windows 也使用 Git。
那么,當你共事于從來沒有聽過現代編程的聰明學生會發生什么呢?他們看一個類似 go get 的命令,只看得到表層(一個命令行)。他們認為這是落后的。漂亮的圖形在哪?
他們使用一個好看的 IDE 工作,像是 Visual Studio 或 Eclipse,并確信自己是現代化的,完全無視 IDE 可以追溯到幾十年前的事實。然后并沒有使用 IDE 的優勢,比如更好的功能可見性和更快的操作,而是在其他地方使用現代化編程技術。他們堅持守舊派編程:
沒有測試。至少,沒有自動化和系統化的測試。
在一個具體的設置上難以處理依賴關系。
沒有自動化。沒有持續集成,沒有自動化部署。
他們編程就像我幾十年前使用 Turbo Pascal 入門的時候。盡管 Turbo Pascal 有圖形化用戶界面(GUI),但它是非常古老的學校。
新聞名稱:go語言bitset go語言和python哪個好
網站鏈接:http://m.newbst.com/article2/dogodic.html
成都網站建設公司_創新互聯,為您提供網站制作、微信公眾號、動態網站、品牌網站建設、電子商務、App開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯