最近在学习Go 语言时,遇到一个很有意思的问题,记录一下。

redisgo
package main

import (
    "fmt"
    "github.com/gomodule/redigo/redis"
)

func main() {
  conn, _ := redis.Dial("tcp", "127.0.0.1:6379")
  defer conn.Close()
  
  conn.Send("SET", "hello", "hello")
  conn.Send("GET", "hello")
  conn.Flush()
  
  v, _ := conn.Receive()
  fmt.Println(v)
}

打印后果:

[104 101 108 108 111]
hello

要答复这个问题,就得理解Go 语言中的字符串这个数据结构了。

意识字符串

字符串是Go 语言中最罕用的根底数据类型之一,尽管字符串往往是被看作是一个整体,但实际上字符串是一块间断的内存空间,也能够了解成是一个由字符组成的数组。

hello[104 101 108 108 111]

作为数组来说,它会占用一片间断的内存空间,这片间断的内存空间就存储了一些字节,这些字节独特组成了字符串。

Go 语言中的字符串是一个只读的字节数组切片

尝试将数组切片转换成字符串:

package main

import "fmt"

func main()  {
  // 留神这里的数据类型是 uint8,而不是 int、uint
    sli := []uint8{104, 101, 108, 108, 111}
    fmt.Println(sli)
    fmt.Printf("%T \n", sli)
    
    fmt.Println(string(sli))       
    fmt.Printf("%T \n", string(sli))
}

打印后果:

[104 101 108 108 111]
[]uint8 
hello
string 
hello
0x680x650x6c0x6c0x6f
hello
0x680x650x6c0x6c0x6f

申明字符串

在Go 语言中,有两种字面量形式能够申明一个字符串,一种是应用双引号,另一种则是应用反引号:

str1 := "this is a string"
str2 := `this is another`

应用双引号申明的字符串其实和其余语言中的字符串申明没有太多区别,它只能用于简略、单行的字符串。

\

在遇到须要写 JSON 或者其余数据格式的场景下十分不便,上面两个 JSON 字符串的写法都没问题,但显然第二种形式更简洁、天然、便于浏览。

str1 := "{\"page\": 1, \"fruits\": [\"apple\", \"pear\"]}"
str2 := `{"page": 1, "fruits": ["apple", "pear"]}`

参考链接

  • 谈 Golang 中的字符串和字节数组