DataWhale & Golang(五、字典、字符串)

DataWhale & Golang(五、字典、字符串)


学习大纲: 


目录

DataWhale & Golang(五、字典、字符串)

学习大纲

补充:

定义字符串 

字符串实现基于 UTF-8 编码

5.1 字典

5.1.1 如何定义字典

5.2 字符串

5.2.1字符串定义

5.2.2 strings包

5.2.3 strconv包

5.2.4 字符串拼接


补充:

package main

 

import "fmt"

 

func main() {

 

//使用make申请一个map,键为string类型,值为int类型

m := make(map[string]int)

 

//设置值

m["k1"] = 7

m["k2"] = 13

 

//取指定键的值

v1 := m["k1"]

fmt.Println("v1: ", v1)

 

//取长度

fmt.Println("len:", len(m))

 

//遍历

for key, value := range m {

fmt.Println(key, ":" , value)

}

//删除

delete(m, "k2")

fmt.Println("map:", m)

 

//初始化时直接指定值

n := map[string]int{"foo": 1, "bar": 2}

fmt.Println("map:", n)

}

定义字符串 

一个字符串是一个不可改变的字节序列,字符串可以包含任意的数据,但是通常是用来包含可读的文本,字符串是 UTF-8 字符的一个序列(当字符为 ASCII 码表上的字符时则占用 1 个字节,其它字符根据需要占用 2-4 个字节)。

UTF-8 是一种被广泛使用的编码格式,是文本文件的标准编码,其中包括 XML 和 JSON 在内也都使用该编码。由于该编码对占用字节长度的不定性,在Go语言中字符串也可能根据需要占用 1 至 4 个字节,这与其它编程语言如 C++Java 或者 Python 不同(Java 始终使用 2 个字节)。Go语言这样做不仅减少了内存和硬盘空间占用,同时也不用像其它语言那样需要对使用 UTF-8 字符集的文本进行编码和解码。

字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容,更深入地讲,字符串是字节的定长数组。

定义字符串,可以使用双引号""来定义字符串,字符串中可以使用转义字符来实现换行、缩进等效果,常用的转义字符包括:

  • \n:换行符
  • \r:回车符
  • \t:tab 键
  • \u 或 \U:Unicode 字符
  • \\:反斜杠自身

字符串实现基于 UTF-8 编码

Go语言中字符串的内部实现使用 UTF-8 编码,通过 rune 类型,可以方便地对每个 UTF-8 字符进行访问。当然,Go语言也支持按照传统的 ASCII 码方式逐字符进行访问。

5.1 字典

       map是一种较为特殊的数据结构(键值对结构),通过给定的key可以快速获得对应的value。

5.1.1 如何定义字典

var m1 map[string]int
m2 := make(map[int]interface{}, 100)
m3 := map[string]string{
	''name'':''james'',
	''age'':''35'',
	}

定义字典时不需要为其指定容量,因为map是可以动态增长的,但是在可以预知map容量的情况下为了提高程序的效率也最好提前标明程序的容量。需要注意的是,不能使用不能比较的元素作为字典的key,例如数组,切片等。而value可以是任意类型的,如果使用interface{}作为value类型,那么就可以接受各种类型的值,只不过在具体使用的时候需要使用类型断言来判断类型。

m3['key1']='v1' //向字典中放入元素:
len(m3)//获取字典的长度

判断键值对是否存在(value是否为空)

if value,ok := m3[''name''];ok{
	fmt.Println(value)
	}

上面这段代码的作用就是如果当前字典中存在key为name的字符串则取出对应的value,并返回true,否则返回false。

遍历字典:

for key,value:=range m3{
	fmt.Println('key:',key,'value:',value)
}

上面这段程序每次的输出顺序并不相同,这是因为对于一个字典来说,默认其是无序的。

(可通过切片使字典有序)

删除字典中的值:使用go的内置函数delete

delete(m3,'key1')

将函数作为值类型存入字典:

func main(){
	m := make(map[string]func(a, b int) int)
	m["add"] = func(a, b int) int {
		return a + b
	}
	m["multi"] = func(a, b int) int {
		return a * b
	}
	fmt.Println(m["add"](3, 2))
	fmt.Println(m["multi"](3, 2))
}

5.2 字符串

5.2.1字符串定义

字符串是一种值类型,在创建字符串之后其值是不可变的。
要修改一个字符串的内容,可以将其转换为字节切片,再将其转换为字符串,但同样需要重新分配内存。

func main(){
	s :='hello'
	b :=[]byte(s)
	b[0]='g'
	s=string(b)
	fmt.Println(s)//gello
}
len(s) //获取字符串长度

但如果字符串中包含中文就不能直接使用byte切片对其进行操作,go语言中我们可以通过这种方式

func main(){
	s := "hello你好中国"
	fmt.Println(len(s)) //17
	fmt.Println(utf8.RuneCountInString(s)) //9

	b := []byte(s)
	for i := 0; i < len(b); i++ {
		fmt.Printf("%c", b[i])
	} //helloä½ å¥½ä¸­å�½
	fmt.Println()

	r := []rune(s)
	for i := 0; i < len(r); i++ {
		fmt.Printf("%c", r[i])
	} //hello你好中国
}

在go语言中字符串都是以utf-8的编码格式进行存储的,所以每个中文占三个字节加上hello的5个字节所以长度为17,如果我们通过utf8.RuneCountInString函数获得的包含中文的字符串长度则与我们的直觉相符合。而且由于中文对于每个单独的字节来说是不可打印的,所以可以看到很多奇怪的输出,但是将字符串转为rune切片则没有问题。

5.2.2 strings包

            strings包提供了许多操作字符串的函数。

func main() {
	var str string = "This is an example of a string"
	//判断字符串是否以Th开头
	fmt.Printf("%t\n", strings.HasPrefix(str, "Th"))
	//判断字符串是否以aa结尾
	fmt.Printf("%t\n", strings.HasSuffix(str, "aa"))
	//判断字符串是否包含an子串
	fmt.Printf("%t\n", strings.Contains(str, "an"))
}

5.2.3 strconv包

            strconv包实现了基本数据类型与字符串之间的转换

i, err := strconv.Atoi("-42") //将字符串转为int类型
s := strconv.Itoa(-42) //将int类型转为字符串

若转换失败则返回对应的error值

5.2.4 字符串拼接

除了以上的操作外,字符串拼接也是很常用的一种操作,在go语言中有多种方式可以实现字符串的拼接,但是每个方式的效率并不相同,下面就对这几种方法进行对比。

1.Sprintf

const numbers = 100

func BenchmarkSprintf(b *testing.B) {
	b.ResetTimer()
	for idx := 0; idx < b.N; idx++ {
		var s string
		for i := 0; i < numbers; i++ {
			s = fmt.Sprintf("%v%v", s, i)
		}
	}
	b.StopTimer()
}

2.+拼接

func BenchmarkStringAdd(b *testing.B) {
	b.ResetTimer()
	for idx := 0; idx < b.N; idx++ {
		var s string
		for i := 0; i < numbers; i++ {
			s += strconv.Itoa(i)
		}
	}
	b.StopTimer()
}

3.bytes.Buffer

func BenchmarkBytesBuf(b *testing.B) {
	b.ResetTimer()
	for idx := 0; idx < b.N; idx++ {
		var buf bytes.Buffer
		for i := 0; i < numbers; i++ {
			buf.WriteString(strconv.Itoa(i))
		}
		_ = buf.String()
	}
	b.StopTimer()
}

4.strings.Builder拼接

func BenchmarkStringBuilder(b *testing.B) {
	b.ResetTimer()
	for idx := 0; idx < b.N; idx++ {
		var builder strings.Builder
		for i := 0; i < numbers; i++ {
			builder.WriteString(strconv.Itoa(i))
		}
		_ = builder.String()
	}
	b.StopTimer()
}

5.对比

BenchmarkSprintf-8         	   68277	     18431 ns/op
BenchmarkStringBuilder-8   	 1302448	       922 ns/op
BenchmarkBytesBuf-8        	  884354	      1264 ns/op
BenchmarkStringAdd-8       	  208486	      5703 ns/op

猜你喜欢

转载自blog.csdn.net/adminkeys/article/details/111385924