日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go语言之标志符可见性

發布時間:2024/1/17 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go语言之标志符可见性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Go的標志符,這個翻譯覺得怪怪的,不過還是按這個起了標題,可以理解為Go的變量、類型、字段等。這里的可見性,也就是說那些方法、函數、類型或者變量字段的可見性。比如哪些方法不想讓另外一個包訪問,我們就可以把它們聲明為非公開的;如果需要被另外一個包訪問,就可以聲明為公開的,和Java語言里的作用域類似。


在Go語言中,沒有特別的關鍵字來聲明一個方法、函數或者類型是否為公開的,Go語言是以大小寫方式進行區分的。如果一個類型的名字是以大寫開頭,那么其他包就可以訪問;如果以小寫開頭,其他包就不能訪問。


package?commontype?count?int package?mainimport?("flysnow.org/hello/common""fmt" )func?main()?{c:=common.count(10)fmt.Println(c) }


這是一個定義在common包里的類型count,因為它的名字以小寫開頭,所以我們不能在其他包里使用它,否則就會報編譯錯誤。


./main.go:9:?cannot?refer?to?unexported?name?common.count


因為這個類型沒有被導出,如果我們改為大寫,就可以正常編譯運行了,大家可以自己試試。


現在這個類型沒有導出,不能使用,我們修改下例子,增加一個函數,看看是否可行。


package?commontype?count?intfunc?New(v?int)?count?{return?count(v) } func?main()?{c:=common.New(100)fmt.Println(c) }


這里我們在common包里定義了一個導出的函數New?,該函數返回一個count類型的值。New函數可以在其他包訪問,但是count類型不可以,現在我們在main包里調用這個New函數,會發現是可以正常調用并且運行的。但是有個前提,必須使用:=這樣的操作符才可以,因為它可以推斷變量的類型。


這是一種非常好的能力。試想,我們在和其他人進行函數方法通信的時候,只需約定好接口就可以了,至于內部實現,使用方是看不到的,隱藏了實現。


package?commonimport?"fmt"func?NewLoginer()?Loginer{return?defaultLogin(0) }type?Loginer?interface?{Login() }type?defaultLogin?intfunc?(d?defaultLogin)?Login(){fmt.Println("login?in...") } func?main()?{l:=common.NewLoginer()l.Login() }


以上例子,我們對于函數間的通信,通過Loginer接口即可,在main函數中,使用者只需要返回一個Loginer接口,至于這個接口的實現,使用者是不關心的。所以接口的設計者可以把defaultLogin類型設計為不可見,并讓它實現接口Loginer,這樣我們就隱藏了具體的實現。如果以后重構這個defaultLogin類型的具體實現,也不會影響外部的使用者,極為方便,這也就是面向接口的編程。


假如一個導出的結構體類型里,有一個未導出的字段,會出現怎樣的問題。


type?User?struct?{Name?stringemail?string }


當我們在其他包聲明和初始化User的時候,字段email是無法初始化的,因為它沒有導出,無法訪問。此外,一個導出的類型,包含了一個未導出的方法也一樣,也是無法訪問的。


我們再擴展,導出和未導出的類型相互嵌入,會有什么什么樣的發現?


type?user?struct?{Name?string }type?Admin?struct?{user }


被嵌入的user是未導出的,但是它的外部類型Admin是導出的,所以外部可以聲明初始化Admin。


func?main()?{var?ad?common.Adminad.Name="張三"fmt.Println(ad) }


這里因為user是未導出的,所以我們不能再使用字面值直接初始化user了,所以只能先定義一個Admin類型的變量,再對Name字段初始化。這里Name可以訪問是因為它是導出的,在user嵌入到Admin中時,它已經被提升為Admin的字段,所以它可以被訪問。


如果我們還想使用:=操作符怎么做呢?


ad:=common.Admin{}


字面值初始化的時候什么都不做就好了,因為user未導出,所以我們不能直接使用字面值初始化Name字段。


還有要注意的是,因為user未導出,所以我們不能通過外部類型訪問內部類型了,也就是說ad.user這樣的操作,都會編譯不通過。


最后,我們做個總結,導出還是未導出,是通過名稱首字母的大小寫決定的,它們決定了是否可以訪問,也就是標志符的可見性。


對于.操作符的調用,比如調用類型的方法,包的函數,類型的字段,外部類型訪問內部類型等,我們要記住.操作符前面的部分導出了,.操作符后面的部分才有可能被訪問;如果.前面的部分都沒有導出,那么即使.后面的部分是導出的,也無法訪問。


例子

可否訪問

Admin.User.Name

Admin.User.name

Admin.user.Name

Admin.user.name


以上表格中Admin為外部類型,User(user)為內部類型,Name(name)為字段,以此來更好的理解最后的總結,當然方法也適用這個表格。


總結

以上是生活随笔為你收集整理的Go语言之标志符可见性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。