理解 Go 语言中的字符串和字节数组

数字拾贝手
• 阅读 2422

最近在学习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 语言中最常用的基础数据类型之一,虽然字符串往往是被看作是一个整体,但实际上字符串是一块连续的内存空间,也可以理解成是一个由字符组成的数组。

字符串虽然在 Go 语言中是基本类型 string(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这个字符串在内存中的存储方式:

理解 Go 语言中的字符串和字节数组

你可能会问:0x680x650x6c0x6c0x6f这些东西是什么?

他们是hello 这个字符串的切片数组的每一个字符的ASCII码所对应的十六进制:

  • h => 104 => 0x68
  • e => 101 => 0x65
  • l => 108 => 0x6c
  • l => 108 => 0x6c
  • o => 111 => 0x6f

声明字符串

在Go 语言中,有两种字面量方式可以声明一个字符串,一种是使用双引号,另一种则是使用反引号:

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

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

并且如果字符串内部出现双引号时需要使用 \ 符号来避免编译器解析错误,而使用反引号则可以很好的摆脱这一限制。

在遇到需要写 JSON 或者其他数据格式的场景下非常方便,下面两个 JSON 字符串的写法都没问题,但显然第二种方式更简洁、自然、便于阅读。

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

参考链接

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
九路 九路
4年前
一篇文章彻底弄懂理解和高效运用切片(slice)
slice,中文多译为“切片”,是Go语言在数组之上提供的一个重要的抽象数据类型。在Go语言中,绝大多数需要使用数组的场合,切片都实现了完美替代。并且和数组相比,切片提供了更通用、功能更强大且便捷的数据序列访问接口。1.切片究竟是什么在对切片一探究竟之前,我们先来简略了解一下Go语言中的数组。Go语言数组是一个固定长度的、容纳同构类型元素的
go语言中,数组与切片的区别?
切片是Go语言核心的数据结构,然而刚接触Go的程序员经常在切片的工作方式和行为表现上被绊倒。比如,明明说切片是引用类型但在函数内对其做的更改有时候却保留不下来,有时候却可以。究其原因是因为我们很多人用其他语言的思维来尝试猜测Go语言中切片的行为,切片这个内置类型在Go语言底层有其单独的类型定义,而不是我们通常理解的其他语言中数组的概念。文章
Wesley13 Wesley13
3年前
Go 定长的数组
1.Go语言数组的简介  几乎所有的计算机语言都有数组,应用非常的广泛。同样,在Go语言中也有数组并且在数组的基础上还衍生出了切片(slice)。数组是一系列同一类型数据的集合,数组中包含的每个数据被称为数组元素,一个数组包含的元素个数被称为数组的长度,这是数组的基本定义。  在Go语言中数组是一个值类型(ValueType)
Stella981 Stella981
3年前
Go语言中的方法(Method Sets)
物以类聚,人以群分。事物必以类分,以形命名。开始一个个学习Go语言中有哪些数据类型,以及这些类型的特点。Go语言中的方法是函数之外一个特别的概念。在Go语言的参考中说:Atypemayhaveamethodsetassociatedwithit(§Interfacetypes,§Methoddeclarations).
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Stella981 Stella981
3年前
Go语言的成功也预示着Rust的成功【转】
从整体的角度来看Go,很难理解他是怎么取得这么大的成功的。从理论的角度上来说Go是一门非常糟糕的语言,就算是和C或者Ada之类旧语言相比也是这样。从整体的角度来看Go,很难理解他是怎么取得这么大的成功的。从理论的角度上来说Go是一门非常糟糕的语言,就算是和C或者Ada之类旧语言相比也是这样。它缺乏大量的编译时的检查和编译时的逻辑,它缺乏销毁逻辑导
Wesley13 Wesley13
3年前
go 学习笔记之10 分钟简要理解 go 语言闭包技术
闭包是主流编程语言中的一种通用技术,常常和函数式编程进行强强联合,本文主要是介绍Go语言中什么是闭包以及怎么理解闭包.如果读者对于Go语言的闭包还不是特别清楚的话,可以参考上一篇文章go学习笔记之仅仅需要一个示例就能讲清楚什么闭包(https://www.oschina.net/ac
Wesley13 Wesley13
3年前
Go 语言初级教程之六[基本类型]
基本类型像C语言一样,Go提供了一系列的基本类型,常见的布尔,整数和浮点数类型都具备。它有一个Unicode的字符串类型和数组类型。同时该语言还引入了两种新的类型:slice和map。数组和切片Go语言当中的数组不是像C语言那样动态的。它们的大小是类型的一部分,在编译时就决定了。数组的索引还是使用的熟悉的
IT全栈视野 IT全栈视野
11个月前
Go开发者成长之路
在Go语言中,成长路径可以包括以下几个阶段:1.安装和配置Go环境:访问Go官网下载并安装Go语言。设置环境变量GOPATH和确保PATH包含Go二进制文件路径。2.学习基础语法:包括变量、函数、控制流、指针、结构体、数组、切片、映射等。3.学习并发编程:
数字拾贝手
数字拾贝手
Lv1
有理的想着说,没理的抢着说。
文章
5
粉丝
0
获赞
0