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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...