Golang——包引入和闭包
包引入:
使用包的原因:
如何引入:
使用package關(guān)鍵字引入,包的路徑就可以使用包下的函數(shù)了,但是被使用的函數(shù)名首字母必須是大寫(xiě)的。
package mainimport ("basics/src/bao" // 這里是引入文件所在包的路徑"fmt" )func main() {fmt.Println("A")bao.Get() // 這里是文件名.函數(shù)名 }utils包
package bao // 這里盡量可以和包名一樣import "fmt"func Get() {fmt.Println("get") }取別名方式導(dǎo)入包:
取別名方式定義好了以后要使用,否則報(bào)錯(cuò)
package mainimport (utils "basics/src/bao" // 這里是引入文件所在包的路徑"fmt" )func main() {fmt.Println("A")utils.Get() // 這里是文件名.函數(shù)名 }包引用后不適用會(huì)報(bào)錯(cuò),可以忽略
import (_"fmt" // 引入了包沒(méi)有用,會(huì)報(bào)錯(cuò),加上下劃線(xiàn)可以忽略"unsafe" )閉包:
- 閉包(closure)是在其詞法上下文中引用了自由變量的函數(shù),或者說(shuō)是函數(shù)和其引用環(huán)境的組合體,總結(jié)就是閉包是一個(gè)函數(shù)和其它引用環(huán)境組合的一個(gè)實(shí)體
- 閉包讓我們不用傳遞參數(shù)就可讀取或修改環(huán)境狀態(tài),當(dāng)然也需要為此付出額外代價(jià)。對(duì)于 性能要求較高的場(chǎng)合,須慎重使用
test返回的匿名函數(shù)會(huì)引用上下文環(huán)境變量x。當(dāng)該函數(shù)在main中執(zhí)行 時(shí),它依然可以正確讀取x的值,這種現(xiàn)象就稱(chēng)作閉包
func test(x int) func() {return func() {println(x)} } func main() {f := test(123)f() }輸出:
123通過(guò)輸出指針,閉包直接引用了原環(huán)境變量。所以說(shuō)閉包是函數(shù)和引用環(huán)境組合體更加確切
func test(x int) func() {println(&x)return func() {println(&x, x)} } func main() {f := test(0x100)f() }輸出:
0xc82000a100 0xc82000a100 256正因?yàn)殚]包通過(guò)指針引用環(huán)境變量,那么可能會(huì)導(dǎo)致其生命周期延長(zhǎng),被分配到堆內(nèi)存。 另一方面,也有所謂延遲求值的特性
func main() {for f := range test() { //迭代執(zhí)行所有匿名函數(shù)f()} }func test() []func() {var s []func()for i := 0; i < 2; i++ {s = append(s, func() { //將多個(gè)匿名函數(shù)添加到列表println(&i, i)})}return s //返回匿名函數(shù)列表 }輸出:
0xc82000a078 2 0xc82000a078 2結(jié)果是一樣的,道理很簡(jiǎn)單,for循環(huán)復(fù)用局部變量i,那么每次添加的匿名函數(shù)引用的自然是同一變量。而且添加操作也僅僅是將匿名函數(shù)放入列表,并未執(zhí)行。因此, 當(dāng)main執(zhí)行這些函數(shù)時(shí),它們讀取的是環(huán)境變量i循環(huán)結(jié)束后的最終值,不是2,還能是什么? 解決方法就是每次用不同的環(huán)境變量,讓各自閉包環(huán)境俱不相同
func test() []func() {var s []func()for i := 0; i < 2; i++ {x := i // x每次循環(huán)都重新定義分配。s = append(s, func() {println(&x, x)})}return s }輸出:
0xc82006e000 0 0xc82006e008 1閉包應(yīng)用:
func main() {f := file(".png")fmt.Println(f("aaa")) }func file(f string) func(string) string {return func(fileName string) string {if !strings.HasPrefix(fileName, f) {return fileName + f}return fileName} }多個(gè)匿名函數(shù)引用同一環(huán)境變量,也會(huì)讓事情變得更加復(fù)雜。任何的修改行為都會(huì)影響其 他函數(shù)取值,在并發(fā)模式下可能需要做同步處理
func main() {a, b := test(100)a()b() }func test(x int) (func(), func()) { // 返回兩個(gè)匿名函數(shù)。return func() {println(x)x += 10 //修改環(huán)境變量。}, func() {println(x) //顯示環(huán)境變量。} }輸出:
100 110總結(jié)
以上是生活随笔為你收集整理的Golang——包引入和闭包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android theme继承原理,an
- 下一篇: ant接口用什么天线_手机听收音机时,为