go系列教程-字元串

来源:https://www.cnblogs.com/e10470252222/archive/2020/04/12/12683412.html
-Advertisement-
Play Games

1、什麼是字元串? Go語言中字元串是一個位元組切片。把內容放在雙引號""之間,我們可以創建一個字元串,讓我們來看一下創建並列印字元串的簡單示例。 package main import ( "fmt" ) func main() { str := "hello golang" fmt.Println ...


1、什麼是字元串?

Go語言中字元串是一個位元組切片。把內容放在雙引號""之間,我們可以創建一個字元串,讓我們來看一下創建並列印字元串的簡單示例。

package main

import (
    "fmt"
)

func main() {
    str := "hello golang"
    fmt.Println(str)
}
線上運行程式
hello golang

2、獲取字元串的每一個位元組

由於字元串是一個位元組切片,所以我們可以獲取字元串的每一個位元組

package main

import (
    "fmt"
)

func main() {
    str := "hello golang"
    printChars(str)
    fmt.Println()
    printBytes(str)
    fmt.Println()
    printCharsAndBytes(str)
}

// 位元組 %x 限定列印字元串位元組
func printBytes(s string) {
    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
}

// 字元  %c 限定列印字元串的字元
func printChars(s string) {
    for i := 0; i < len(s); i++ {
        fmt.Printf("%c  ", s[i])
    }
}

// for range 迴圈是最簡單方法方
func printCharsAndBytes(s string) {
    for _, rune := range s {
        fmt.Printf("%c starts at byte %x\n", rune, rune)
    }
}
線上運行程式
h  e  l  l  o     g  o  l  a  n  g  
68 65 6c 6c 6f 20 67 6f 6c 61 6e 67 
h starts at byte 0
e starts at byte 1
l starts at byte 2
l starts at byte 3
o starts at byte 4
  starts at byte 5
g starts at byte 6
o starts at byte 7
l starts at byte 8
a starts at byte 9
n starts at byte a
g starts at byte b
airdeMacBook-Air:learn_demo wutianxiang$ go run main.go 
h  e  l  l  o     g  o  l  a  n  g  
68 65 6c 6c 6f 20 67 6f 6c 61 6e 67 
h starts at byte 68
e starts at byte 65
l starts at byte 6c
l starts at byte 6c
o starts at byte 6f
  starts at byte 20
g starts at byte 67
o starts at byte 6f
l starts at byte 6c
a starts at byte 61
n starts at byte 6e
g starts at byte 67

如果我們再上面基礎上字元串含中文,那會如何?

package main

import (
    "fmt"
)

func main() {
    str := "hello golang 語言"
    printChars(str)
    fmt.Println()
    printBytes(str)
    fmt.Println()
    printCharsAndBytes(str)
}

// 位元組 %x 限定列印字元串位元組
func printBytes(s string) {
    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
}

// 字元  %c 限定列印字元串的字元
func printChars(s string) {
    for i := 0; i < len(s); i++ {
        fmt.Printf("%c  ", s[i])
    }
}

// for range 迴圈是最簡單方法方
func printCharsAndBytes(s string) {
    for _, rune := range s {
        fmt.Printf("%c starts at byte %x\n", rune, rune)
    }
}
線上運行程式
h  e  l  l  o     g  o  l  a  n  g     è  ¯  ­  è  ¨    
68 65 6c 6c 6f 20 67 6f 6c 61 6e 67 20 e8 af ad e8 a8 80 
h starts at byte 68
e starts at byte 65
l starts at byte 6c
l starts at byte 6c
o starts at byte 6f
  starts at byte 20
g starts at byte 67
o starts at byte 6f
l starts at byte 6c
a starts at byte 61
n starts at byte 6e
g starts at byte 67
  starts at byte 20
語 starts at byte 8bed
言 starts at byte 8a00

上面第一行輸出了錯誤 h e l l o g o l a n g è ¯ ­ è ¨ 

為什麼程式分割 hello golang 時表現完美,但分割字元含中文就錯誤?

這是“語言”的unicode代碼點(code point)是U+00F1。他的UTF-8編碼占用了 e8 af ad e8 a8 80

6個位元組。

它的UTF-8編碼占用了8個位元組 e8 af ad e8 a8 80。而我們列印字元時,卻假定每個字元的編碼只會占用一個位元組,這是錯誤的。

在UTF-8編碼中,一個代碼點可能會占用超過一個位元組的空間。

那麼我們該怎麼辦呢?

rune 能幫我們解決這個難題。

rune是Go語言的內建類型,它是int32的別稱。在Go語言中,rune表示一個代碼點,無論代碼點占用多少個位元組,都可以用一個rune來表示

package main

import (
    "fmt"
)

func main() {
    str := "hello golang 語言"
    printChars(str)
    fmt.Println()
    printBytes(str)
    fmt.Println()
    printCharsAndBytes(str)
}

// 位元組 %x 限定列印字元串位元組
func printBytes(s string) {
    for i := 0; i < len(s); i++ {
        fmt.Printf("%x ", s[i])
    }
}

// 字元  %c 限定列印字元串的字元
func printChars(s string) {
    runes := []rune(s)
    for i := 0; i < len(runes); i++ {
        fmt.Printf("%c  ", runes[i])
    }
}

// for range 迴圈是最簡單方法方
func printCharsAndBytes(s string) {
    for _, rune := range s {
        fmt.Printf("%c starts at byte %x\n", rune, rune)
    }
}
線上運行程式
h  e  l  l  o     g  o  l  a  n  g     語  言  
68 65 6c 6c 6f 20 67 6f 6c 61 6e 67 20 e8 af ad e8 a8 80 
h starts at byte 68
e starts at byte 65
l starts at byte 6c
l starts at byte 6c
o starts at byte 6f
  starts at byte 20
g starts at byte 67
o starts at byte 6f
l starts at byte 6c
a starts at byte 61
n starts at byte 6e
g starts at byte 67
  starts at byte 20
語 starts at byte 8bed
言 starts at byte 8a00

3、用位元組切片構造字元串

package main

import (
    "fmt"
)

func main() {
    // 十六進位
    byteSlice := []byte{0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x67, 0x6F, 0x6C, 0x61, 0x6E, 0x67, 0x20, 0xE8, 0xAF, 0xAD, 0xE8, 0xA8, 0x80}
    str := string(byteSlice)
    fmt.Println(str)
}
線上運行程式
hello golang 語言

4、rune 切片構造字元串

package main

import (
    "fmt"
)

func main() {
    runeSlice := []rune{104, 101, 108, 108, 111, 32, 103, 111, 108, 97, 110, 103, 32, 35821, 35328}
    str := string(runeSlice)
    fmt.Println(str)
}
線上運行程式
hello golang 語言
5、獲取字元串長度
對於字母數字組合成字元串獲取長度,用len()方法;
對於中文或其它國家文字組成字元串獲取長度,用utf8.RuneCountInString()方法
package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    str1 := "hello"
    length(str1)
    str2 := "hello您好"
    length(str2)
}

// 獲取字元串長度
func length(s string) {
    fmt.Printf("length of %s is %d\n", s, utf8.RuneCountInString(s))
}

6、字元串是不可變的。一旦創建一個字元串,那麼他將無法被修改。如果試圖把字元串修改,程式會拋出一個錯誤:cannot assign to s[0]

package main

import (
    "fmt"
)

func main() {
    str := "hello"
    fmt.Println(midfyString(str))
}

// 修改字元串
func midfyString(s string) string {
    s[0] = 'a'
    return s
}

上面這個操作是非法的。

那麼如果修改字元,可以把字元串轉化一個rune切片,然後對這個切片任何修改,再將轉化一個新的字元串

package main

import (
    "fmt"
)

func main() {
    str := "hello"
    fmt.Println(midfyString(str))
    fmt.Println(str)
}

// 修改字元串
func midfyString(s string) string {
    runes := []rune(s)
    // 註意這個是單引號。如果改成雙引號,可以試試發生什麼
    runes[0] = 'a'
    return string(runes)
}

7、字元串拼接,後續。。


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

-Advertisement-
Play Games
更多相關文章
  • 自己製作單選框樣式: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <titl ...
  • 申明:本文轉載至:https://github.com/dawn-plex/translate/blob/master/articles/5-Tips-to-Write-Better-Conditionals-in-JavaScript.md 感謝作者,感謝分享 原文地址:5 Tips to Wri ...
  • 最近看到一個有意思的圖片,包含了鮮為人知的秘密。。。 先看看這張有意思的圖片。 圖左應該講的是基督教中的三位一體。翻譯成中文如下。 當然這不是我們的重點,我們的重點在右邊這個圖。講的是js中相等操作。 是js中的寬鬆相等(loose equals)。 是嚴格相等(strict equals)。 這兩 ...
  • thrift類似java裡面的socket和sockchannel中server和client通信 thrift最重要的是跨語言,裡面提供了序列化和反序列化、json和實體對象等方法 Apache Thrift軟體框架(用於可擴展的跨語言服務開發)將軟體堆棧與代碼生成引擎結合在一起,以構建可在C++ ...
  • 作為一個碼農,你知道如何啟動一個java線程嗎? 啟動線程 public class PrintThread extends Thread { public void run() { System.out.println("我是線程! 繼承自Thread"); } public static voi ...
  • 全民閱讀的時代已經來臨,目前使用讀書軟體的用戶數2.1億,日活躍用戶超過500萬,其中19-35歲年輕用戶占比超過60%,本科及以上學歷用戶占比高達80%,北上廣深及其他省會城市/直轄市用戶占比超過80%。**本人習慣使用微信讀書,為了方便整理書籍和導出筆記,便開發了這個小工具。** ...
  • 前言 在【JAVA進階架構師指南】系列二和三中,我們瞭解了JVM的記憶體模型以及類載入機制,其中在記憶體模型中,我們說到,從線程角度來說,JVM分為線程私有的區域(虛擬機棧/本地方法棧/程式計數器)和線程公有區域(方法區和java堆),其中線程私有區域記憶體隨著線程的結束而跟著被回收,GC主要關註的是堆和 ...
  • 靈魂拷問:在不重啟服務的前提下,如何讓配置修改生效的呢?有什麼奇技淫巧嗎? 靈魂拷問:在 Java 項目中,總能看到以 .properties 為尾碼的文件蹤影,這類配置文件是怎麼載入的呢? 項目研發過程中,總會遇到一些經常改變的參數,比如要連接的資料庫的連接地址、名稱、用戶名、密碼;再比如訪問三方 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...