0
点赞
收藏
分享

微信扫一扫

反引号和单引号的区别 字符串拼接 类型转换 类型转换 UTF编码 string和[]byte如何取舍

程序猿不脱发2 2022-04-03 阅读 64
开发语言

1.双引号与反单引号的区别

字符串可以使用双引号赋值,也可以使用反单引号赋值(注意不是单引号),它们的区别在于对特殊字符的处理。
假如,我们希望string变量表示下面的字符串,它包括换行符和双引号。
 

Hi,
this is "RainbowMango".

使用双引号表示时,需要对特殊字符转义,如下所示。
 

S:="Hi, \nthis is \"RainbowMangol\"."

两种方式的对比,

1.使用双引号表示的时候,需要对特殊的字符进行转义

2.使用反单引号表示的时候,不需要对特殊字符进行转义

package main
func main(){

	s := `Hi,
this is "RainbowMango"`
	print(s,"\n")
	s1 := "Hi,\nthis is \"RainbowMango\"."
	print(s1)
}

输出如下:

Hi,
this is "RainbowMango"
Hi,
this is "RainbowMango".

2.字符串拼接

字符串可以使用加号进行拼接:
 

s = s + "a" + "b"

需要注意的是,字符串拼接的时候会出发内存分配以及内存的拷贝,单行语句拼接多个字符串只分配一次内存。在拼接的时候,会先计算最终字符串的长度后再分配内存。

3.类型转换

项目中,数据经常需要在string和字节切片([ ]byte) 之间转换。string和byte[ ]进行转换:
 

package main

import "fmt"
func main(){
	b := []byte{'H', 'e', '1', '1', 'o'}
	fmt.Println(b)
	fmt.Println(b[0])
	s:= string(b)
	fmt. Println(s)
}

输出如下:

[72 101 49 49 111]
72
He11o

[ ]byte 转 string类型:

import "fmt"
func main(){
	b := "Hello"
	a :=[]byte(b)

	fmt. Println(a)
}

需要注意的是,无论是字符串转换成[ ]byte,还是[ ]byte转换成string,都将发生一次内存拷贝,会有一定的开销。

4.UTF编码

string使用8比特字节的集合来存储字符,而且存储的是字符的UTF-8编码,例如每个汉字字符的UTF-8编码将占用多个字节。

在使用for-range遍历字符串的时候,每次迭代将返回字符UTF-8编码的首个字节的下表以及字节值,这意味着下标可能不连续。

例如下面的,输出如下图:

此外,字符串的长度是指字节数,而非字符数,比如汉字“中”和“国”的UTF-8编码各占3个字节,字符串“中国”的长度为6而不是2。
 

import "fmt"
func main(){
	s := "中国"
	for index , value := range s{
		fmt.Printf("index : %d , value: %c\n",index,value)
	}
}
index : 0 , value: 中
index : 3 , value: 国

5.字符串的值不可修改

字符串可以为空,但值不会是nil。另外,字符串不可以修改。字符串变量可以接受新的字符串赋值,但不能通过下标方式修改字符串中的值。
比如下面的代码,尝试将字母“H”修改为小写:
 

s :="Hello"
&s[0] = byte (104)//非法
s = "hello"//合法

字符串不支持取地址操作,也就无法修改字符串的值,上面的语句中会出现编译错误:
 

cannot take the address of s[0]

6.string和[]byte如何取舍

string和[]byte都可以表示字符串,但因数据结构不同,其衍生出来的方法也不同,要根据实际应用场景来选择。

string擅长的场景:
需要字符串比较的场景;

不需要nil字符串的场景。


[ ]byte 擅长的场景:
修改字符串,尤其是修改粒度为1个字节的场景;

函数返回值,需要用nil表示含义的场景;

需要切片操作的场景。


虽然看起来string适用的场景不如[]byte多,但因为string直观,在实际应用中还是大量存在的,在偏底层的实现中[ ]byte使用得更多。
 

举报

相关推荐

0 条评论