Go xmas2020 全英課程 04 學習筆記、Strings

来源:https://www.cnblogs.com/linxiaoxu/archive/2022/04/02/16089973.html
-Advertisement-
Play Games

課程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com) 主講老師 Matt Holiday 04-Strings Strings 字元串在 go 中都是 unicode ,unicode 是一種特 ...


課程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com)

主講老師 Matt Holiday

image-20220401081031592

04-Strings

Strings

image-20220402025441130

字元串在 go 中都是 unicode ,unicode 是一種特殊的技術用於表示國際通用字元。

rune 相當於 wide character,是 int32 的同義詞,四個位元組足夠大,任何 unicode、字元,邏輯字元 可以指向它。

但是為了讓程式更高效,我們不想一直用 4 個位元組表示每個字元,因為很多程式使用 ascii 字元。

因此有一種稱為 utf-8 編碼的 unicode 技術,以位元組 byte 表示 unicode 的簡便方法。

從物理角度上看,strings 就是 unicode 字元的 utf-8 編碼。


ascii characters 適合 0-127 的範圍

func main() {
	s := "élite"

	fmt.Printf("%8T %[1]v %d\n", s, len(s))
	fmt.Printf("%8T %[1]v\n", []rune(s))
	b := []byte(s)
	fmt.Printf("%8T %[1]v %d\n", b, len(b))
}
  string élite 6
 []int32 [233 108 105 116 101]
 []uint8 [195 169 108 105 116 101] 6

é 為 233 超出了 ascii 的表示範圍,由 2 個位元組表示,而不是為每個字元使用 4 個位元組,這是 utf8 編碼的效果。中文字經常為 20000 的數字,五個中文字會用 15 個位元組表示。


len(s) 顯示 6 的原因,在程式中字元串的長度是在 utf-8 中編碼字元串所必需的位元組字元串的長度

The length of a string in the program is the length of the byte string that's necessary to encode the string in utf-8,not the number of unicode characters

就是說給定一個字元串,把它進行 utf-8 編碼需要的位元組數量就是它的長度,而不是 unicode 字元的數量。


String structure

image-20220402031112990

可以把圖片左邊的 s 理解為一個描述符(描述符不是指針、不是 go 的專業術語),它有指針和額外的信息(位元組數)。

go 字元串末尾沒有空位元組,很多編程語言通過迴圈字元串判斷空位元組獲取長度,效率並不高。在 go 中字元串長度直接保存在描述符中。


通過索引字元串創建 hello 的時候,hello 的 data 指向的是跟 s 描述符 data 的相同記憶體地址(共用存儲)。

因為字元串沒有空位元組,而且它們是不可變的,所以共用存儲是完全可行的。world 也是同理。它們重用 s 中的記憶體。


t := s 的結果是 t 將有與 s 一樣的內容,但是 t 跟 s 是不一樣的描述符。

image-20220402032338925

b、c 與 s 共用存儲。

d 開闢了新的記憶體空間,存入了新的字元串。

s[5] = 'a' 出錯,字元串是不可變的,不能單獨修改字元串。

s +="es" 相當於 s = s + "es" ,開闢了新的記憶體空間,複製原有內容,再添加新內容,並使 data 指向新的記憶體地址。

原來的字元串並沒有改變、消失,因為 b、c 依舊指向原來的記憶體地址,s 指向了新開闢的記憶體地址。


String functions

image-20220402032835785

s = strings.ToUpper(s) 字元串不允許被更改,所以會創建新字元串進行舊字元串的拷貝並大寫。由於開闢了新的記憶體空間,將返回值給 s 也就很好理解了。


如果沒有變數引用字元串,它會自動被垃圾回收。


Practice

做一個替換句子中指定單詞的程式

main.go

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	if len(os.Args) < 3 {
		fmt.Fprintln(os.Stderr, "not enough args")
		os.Exit(-1)
	}

	old, new := os.Args[1], os.Args[2]
	scan := bufio.NewScanner(os.Stdin)

	for scan.Scan() {
		s := strings.Split(scan.Text(), old)
		t := strings.Join(s, new)

		fmt.Println(t)
	}
}

os.Args 運行 go 程式時附加的參數,具體可以看前幾節的內容。

buffio.NewScanner(os.Stdin) 掃描儀是一個緩衝io工具,預設以行分割輸入的內容。舉個例子,如果輸入特別大,就可以把它以一系列行的形式讀取。

scan.Scan() 將迴圈讀取行,如果有可用的行讀取將會返回true。

scan.Text() 獲取讀取的行。

for 迴圈中使用 strings 標準庫的 Split 方法根據舊單詞 變數 old(大小寫敏感)分割字元串獲得字元串切片。

再將切片傳入 strings 標準庫的 Join 方法,通過新單詞 變數 new 合併字元串。


test.txt

matt went to greece
where did matt go
alan went to rome
matt didn't go there

第一行留空行,因為會讀取 BOM 頭,具體請看這篇文章
重定向管道流讀取TXT文本第一次讀取為""空字元串 - 小能日記 - 博客園 (cnblogs.com)


result

cat test.txt | go run . matt ed

ed went to greece
where did ed go
alan went to rome
ed didn't go there

這裡我們使用了重定向管道,讀取 test.txt 的內容當做 main.go 的程式輸入,指令在 linux 是 go run . matt ed < test.txt。


	old, new := os.Args[1], os.Args[2]
	old, new = new, old

值得註意的一點是初始化變數的方式,使用一行初始化兩個變數。巧妙的是可以用這種方式進行兩個變數值的交換


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、創建一個Flutter工程🔥 🔺1.1 命令行創建 首先我們找一個空目錄用來專門存放flutter項目,然後在路徑中直接輸入cmd: 使用 flutter create <projectname> 命令創建flutter項目: 創建成功: 進入項目根目錄中,執行 flutter run 命令 ...
  • 本次為大家帶來的是 DevEco Device Tool 3.0 Release,新增四項新功能,歡迎大家升級體驗! ...
  • 前言 ​ 我們先瞭解 UIViewController 生命周期相關的內容和 iOS 的“黑魔法” Method Swizzling。然後再瞭解頁面瀏覽事件($AppViewScreen)全埋點的實現原理 一、UIViewController 生命周期 ​ 眾所周知,每一個 UIViewContro ...
  • 更新概覽 支持轉化事件回傳至華為應用市場商業推廣,便捷歸因,實時調優。 卸載分析模型支持用戶卸載前事件和路徑分析,深度剖析卸載根因。 實時漏斗體驗開放,靈活定位異常流失。 詳情介紹 更新一:全面開放深度轉化事件回傳 在歸因原理中,轉化事件回傳是關鍵環節之一,對廣告投放平臺的模型訓練以及廣告投放效果的 ...
  • 1. innerHTML() 創建元素 是將內容寫入某個DOM節點中,單個創建元素沒有什麼影響,如果利用for迴圈拼接多個字元串的形式創建元素的話會出現執行時間的不一樣,導致效率很慢;如果想要創建多個元素的效率更高可以不用拼接字元串,而是採取數組形式拼接,但是這種方式結構稍微複雜了點,不會導致頁面的 ...
  • webpack是開發工具,面試考點重點在配置和使用,原理理解不需要太深。 一、基本配置 1、拆分配置和merge 將公共配置跟dev和prod的配置拆分,然後通過webpack-merge對配置進行整合。 2、啟動本地服務 dev環境啟動devserver配置。 3、處理ES6 使用babel-lo ...
  • 2545光年之外的開普勒1028星系,有一顆色彩斑斕的宜居星球 🌑,星際移民 👨‍🚀 必須穿戴基地發放的防輻射服才能生存。阿狸 🦊 駕駛星際飛行器 🚀 降臨此地,快幫它在限定時間內使用輪盤移動找到基地獲取防輻射服吧!本文使用 Three.js + React + CANNON 技術棧,實現... ...
  • 組合模式是什麼 組合模式:是一種結構型設計模式, 你可以使用它將對象組合成樹狀結構, 並且能像使用獨立對象一樣使用它們。 為什麼用組合模式 如果你需要實現樹狀對象結構,可以使用組合模式。確保應用的核心模型能夠以樹狀結構表示。 嘗試將其分解為簡單元素和容器。 記住,容器必須能夠同時包含簡單元素和其他容 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...