Go语言圣经第五章-函数
strings.Map
- 定义:
func Map(mapping func(rune) rune, s string) string - 作用: 对字符串的每一个字符进行修改,替换或删除,生成一个新的字符串
主要作用取决于mapping这个函数的返回值,如果返回一个新的合法字符,那么就会替换,如果返回原来的字符就不变,如果返回-1就删除这个字符
- 为什么要使用strings.Map?自己使用for循环不也能做到这些吗
- 可以处理UTF-8字符,go的字符串的底层是[]byte,如果直接使用循环遍历,处理中文会乱码。strings.Map会自动把字符串解码为Runes,适合处理中文等
- 更高效,strings.Map内部使用了strings.Builder,相比于循环拼接时更高效
- 使用函数值,我们可以将遍历结点的逻辑和操作结点的逻辑分离,使得我们可以复用遍历的逻辑,从而对结点进行不同的操作。
匿名函数
函数squares返回另一个类型为 func() int 的函数。对squares的一次调用会生成一个局部变量x并返回一个匿名函数。每次调用匿名函数时,该函数都会先使x的值加1,再返回x的平方。第二次调用squares时,会生成第二个x变量,并返回一个新的匿名函数。新匿名函数操作的是第二个x变量。
squares的例子证明,函数值不仅仅是一串代码,还记录了状态。在squares中定义的匿名内部函数可以访问和更新squares中的局部变量,这意味着匿名函数和squares中,存在变量引用。这就是函数值属于引用类型和函数值不可比较的原因。Go使用闭包(closures)技术实现函数值,Go程序员也把函数值叫做闭包。
通过这个例子,我们看到变量的生命周期不由它的作用域决定:squares返回后,变量x仍然隐式的存在于f中。
闭包对循环变量的捕获
这是go1.22前的行为,在1.22之后,每次循环迭代,循环变量都会重新创建了,这个特性可以忽略了
- 当你在 for 循环里创建一个函数(闭包),并且这个函数里用到了循环变量(比如 dir),这个函数记下的不是当时那个 dir 的值,而是 dir 这个变量本身的地址。
1 | var rmdirs []func() |
为什么使用d赋值一个新的变量,而不是使用下面这样
1 | var rmdirs []func() |
defer
- defer 关键字只负责延迟“最外层”的那个函数调用,而为了拿到那个被延迟执行的函数,Go 必须先“立即”执行前面的代码
defer trace("big")()实际等同于
1 | returnedFunc := trace("big") |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 EurekaYu!
评论




