Golang学习笔记-1.15 字符串

栏目: Go · 发布时间: 6年前

内容简介:Go 语言中的字符串是一个字节切片. 把内容放在双引号之间, 就可以创建一个字符串.程序输出:由于字符串是字节切片, 所以可以获取字符串的每一个字节.

本文系第十五篇Golang语言学习教程

什么是字符串

Go 语言中的字符串是一个字节切片. 把内容放在双引号之间, 就可以创建一个字符串.

package main

import "fmt"

func main() {
  name := "hello world"
  fmt.Println(name)
}

程序输出: hello world
Go 中字符串是兼容 Unicode 编码的, 并且使用 UTF-8 进行编码.

单独获取字符串的每一个字节

由于字符串是字节切片, 所以可以获取字符串的每一个字节.

package main

import "fmt"

func printbytes(s string) {  //定义函数
    for i := 0; i < len(s); i++ {   //len(s) 返回字符串中字符的数量
        fmt.Printf( "%x ", s[i])   //%x 指定打印字符串的16进制编码
    }
}

func printchars(s string) {
    for i := 0; i< len(s); i++ {
        fmt.Printf("%c ", s[i])   //%c  指定打印字符串的字符
    }
}

func main() {
    name := "hello world"
    printbytes(name)
    fmt.Println("\n")
    printchars(name)
}

上面程序中, len(s) 用于返回字符串的字符数量, %x 指定打印字符串的16进制编码, %c 用于指定打印字符串的数量.

以上程序输出为:

68 65 6c 6c 6f 20 77 6f 72 6c 64  h e l l o w o r l d

上面的程序获取字符串的每一个字符,虽然看起来是合法的,但却有一个严重的 bug。让我拆解这个代码来看看我们做错了什么。

package main

import "fmt"

func printbytes(s string) {  //定义函数
    for i := 0; i < len(s); i++ {   //len(s) 返回字符串中字符的数量
        fmt.Printf( "%x ", s[i])   //%x 指定打印字符串的16进制编码
    }
}

func printchars(s string) {
    for i := 0; i< len(s); i++ {
        fmt.Printf("%c ", s[i])   //%c  指定打印字符串的字符
    }
}


func main() {
    name := "hello world"
    printbytes(name)
    fmt.Println("\n")
    printchars(name)
    name = "Señor"  
    fmt.Println("\n")
    printchars(name)
}

以上程序中,我们尝试输出 Señor 的字符,但却输出了错误的 S e à ± o r 。 为什么程序分割 Hello World 时表现完美,但分割 Señor 就出现了错误呢?这是因为 ñ 的 Unicode 代码点(Code Point)是 U+00F1 。它的 UTF-8 编码 占用了 c3 和 b1 两个字节。它的 UTF-8 编码占用了两个字节 c3 和 b1。而我们打印字符时,却假定每个字符的编码只会占用一个字节,这是错误的。在 UTF-8 编码中,一个代码点可能会占用超过一个字节的空间。那么我们该怎么办呢?rune 能帮我们解决这个难题。

rune

rune 是 Go 语言的内建类型,它也是 int32 的别称。在 Go 语言中,rune 表示一个代码点。代码点无论占用多少个字节,都可以用一个 rune 来表示。让我们修改一下上面的程序,用 rune 来打印字符。

package main

import "fmt"

func printbytes(s string) {  //定义函数
    for i := 0; i < len(s); i++ {   //len(s) 返回字符串中字符的数量
        fmt.Printf( "%x ", s[i])   //%x 指定打印字符串的16进制编码
    }
}

func printchars(s string) {
    runes := []rune(s)  //字符串被转化为一个 rune 切片
    for i := 0; i< len(s); i++ {
        fmt.Printf("%c ", runes[i])   //%c  指定打印字符串的字符
    }
}

func main() {
    name := "hello world"
    printbytes(name)
    fmt.Println("\n")
    printchars(name)
    name = "Señor"
    fmt.Println("\n")
    printchars(name)
}

以上程序中, 将字符串转化为一个 rune 的切片.

程序输出为:

68 65 6c 6c 6f 20 77 6f 72 6c 64  h e l l o w o r l d  S e ñ o r

字符串是不可变的

Go中的字符串是不可变的, 一旦创建无法更改:

package main

import (  
    "fmt"
)

func mutate(s string)string {  
    s[0] = 'a'//any valid unicode character within single quote is a rune 
    return s
}
func main() {  
    h := "hello"
    fmt.Println(mutate(h))
}

以上程序中想要把 h 的第一个字符变成 a, 却报错: main.go:8: cannot assign to s[0] , 由此可以看出,字符串不允许修改.

为了修改字符串,可以把字符串转化为一个 rune 切片。然后这个切片可以进行任何想要的改变,然后再转化为一个字符串。

package main

import (  
    "fmt"
)

func mutate(s []rune) string {  
    s[0] = 'a' 
    return string(s)
}
func main() {  
    h := "hello"
    fmt.Println(mutate([]rune(h)))
}

以上程序中, 函数 mutate 接收到一个 rune 切片的传入, 将第一个字符更改为 a , 然后转换为字符串输出. 所以以上程序输出为: aello

以上为学习Golang 字符串


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning XSLT 2.0

Beginning XSLT 2.0

Jeni Tennison / Apress / 2005-07-22 / USD 49.99

This is an updated revision of Tennison's "Beginning XSLT", updated for the new revision of the XSLT standard. XSLT is a technology used to transform an XML document with one structure into another ......一起来看看 《Beginning XSLT 2.0》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换