Go组队学习 4.字典、字符串

本文探讨了Go语言中的字典和字符串。字典允许通过键值对进行存储,支持插入、检查键值对存在及删除操作,且字典是无序的。在遍历字典时要注意顺序的不确定性。字符串在Go中是不可变的,可以通过多种方式拼接,如SPrintf、+运算、bytes.Buffer和strings.Builder。其中,strings.Builder提供了高效的字符串拼接方式。
摘要由CSDN通过智能技术生成

字典

map是一种键值对结构,可以通过key找到对应的value。

  • map是引用类型
  • map是使用Hash实现的
  • Map是无序键值对
  • len()函数返回Map的key的个数
  • map的key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型,如果使用interface{}作为value类型,那么就可以接受各种类型的值,只不过在具体使用的时候需要使用类型断言来判断类型。
  • 定义字典时不需要为其指定容量,因为map是可以动态增长的

定义字典

/* 声明变量,默认 map 是 nil 
key为int类型,value为string类型
*/
var map_variable map[int]string

/* 使用 make 函数 */
map_variable = make(map[int]string)
//声明同时赋值
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对。

插入值

m3["key1"] = "v1"
m3["key2"] = "v2"
m3["key3"] = "v3"

若使用相同的key,会覆盖。
不仅如此我们还可以将函数作为值类型存入到字典中。

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))
}

确定键值对是否存在:

如果当前字典中存在key为name的字符串则取出对应的value,并返回true,否则返回false。

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

遍历字典

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

注意每次输出顺序不一定,因为字典是无序的

删除字典中元素

删除key即可

delete(m3, "key1")

字符串

Go中的字符串是一个字节的切片。字符串是一种值类型,在创建字符串之后其值是不可变的,go语言中是通过长度来标识字符串是否结束的。

如果我们想要修改一个字符串的内容,我们可以将其转换为字节切片,再将其转换为字符串,但是也同样需要重新分配内存。

func main() {
	s := "hello"
	b := []byte(s)
	b[0] = 'g'
	s = string(b)
	fmt.Println(s) //gello
}

如果字符串中包含中文就不能直接使用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切片则没有问题。

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"))
}

strconv包

可以实现string和其他数值类型之间的转换。

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

字符串拼接

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()
}
结果对比

在这里插入图片描述
通过strings.Builder拼接字符串是最高效的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值