zoukankan      html  css  js  c++  java
  • go系列教程-字符串

    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
    ", 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
    ", 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
    ", 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
    ", 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、字符串拼接,后续。。

  • 相关阅读:
    【SQL】开窗函数简介
    【博客园美化】参考链接汇总(持续更新中……)
    【SQL】牛客网SQL试题练习(更新到11题)
    【SQL】SQL和MySQL语句的执行顺序
    【数据分析项目】淘宝用户行为分析【SQL+Tableau】
    【数据分析项目】婴儿商品消费情况分析【Excel】
    【Sublime Text 3】前端常用快捷键
    【Excel】常用快捷键
    MongoDB 规范
    mongodb 常用命令
  • 原文地址:https://www.cnblogs.com/e10470252222/p/12683412.html
Copyright © 2011-2022 走看看