中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

移動(dòng)網(wǎng)站的開(kāi)發(fā)流程圖搜索引擎培訓(xùn)班

移動(dòng)網(wǎng)站的開(kāi)發(fā)流程圖,搜索引擎培訓(xùn)班,dw軟件的使用方法,網(wǎng)站建設(shè)jsp文章目錄 接口:one: 接口基礎(chǔ):two: 接口類型斷言和空接口:star2: 空接口實(shí)現(xiàn)存儲(chǔ)不同數(shù)據(jù)類型的切片/數(shù)組:star2: 復(fù)制切片到空接口切片:star2: 類型斷言 反射 📅 2024年5月9日 📦 使用版本為1.21.5 接口 十、Java類的封裝和繼承、多態(tài) - 七點(diǎn)半的菜市…

文章目錄

    • 接口
      • :one: 接口基礎(chǔ)
      • :two: 接口類型斷言和空接口
        • :star2: 空接口實(shí)現(xiàn)存儲(chǔ)不同數(shù)據(jù)類型的切片/數(shù)組
        • :star2: 復(fù)制切片到空接口切片
        • :star2: 類型斷言
    • 反射

📅 2024年5月9日

📦 使用版本為1.21.5

接口

十、Java類的封裝和繼承、多態(tài) - 七點(diǎn)半的菜市場(chǎng) (tanc.fun) Java的接口

ps: 我感覺(jué)Go的接口和類方法兩個(gè)就很模糊

1?? 接口基礎(chǔ)

?? 接口就是一些未實(shí)現(xiàn)功能的集合(我是這樣理解的),為了實(shí)現(xiàn)多態(tài)(就是多狀態(tài))

type PersonIF interface {Status() //人類的狀態(tài)Skills() string //會(huì)的技能
}

?? 在Go語(yǔ)言中接口可以有值,它的值默認(rèn)是nil,接口本質(zhì)上是一個(gè)指針,一個(gè)類型如果實(shí)現(xiàn)了接口中的所有方法,那么這個(gè)類實(shí)現(xiàn)的方法就會(huì)使用指針自動(dòng)指向接口的方法

?? 注意是所有抽象方法,如果有一個(gè)沒(méi)實(shí)現(xiàn)都會(huì)報(bào)錯(cuò)

?? 類型不需要使用什么關(guān)鍵字來(lái)表面實(shí)現(xiàn)了這個(gè)接口,多個(gè)類型可以同時(shí)實(shí)現(xiàn)一個(gè)接口,一個(gè)類型也可以實(shí)現(xiàn)多個(gè)接口

type PersonIF interface {Status()Skills()
}type WorkIF interface {Class()Income()
}type Person struct { //人的基本Name stringage  intsex  string
}/*Person實(shí)現(xiàn)PersonIF接口
*/
func (this *Person) Status() {println("Status")
}func (this *Person) Skills() {println("Skills")
}/*Person實(shí)現(xiàn)WorkIF接口*/
func (this *Person) Class() {println("Class")
}	
func (this *Person) Income() {println("Income")
}

?? 調(diào)用則和Java差不多,這里可以直接使用Interfer來(lái)創(chuàng)建一個(gè)變量調(diào)用,然后就可以調(diào)用實(shí)現(xiàn)interfer內(nèi)的方法

type PersonIF interface {Status()Skills()
}type WorkIF interface {Class()Income()
}type Person struct { //人的基本Name stringage  intsex  string
}/*
Person實(shí)現(xiàn)PersonIF接口
*/
func (this *Person) Status() {println("Status")
}func (this *Person) Skills() {println("Skills")
}/*
Person實(shí)現(xiàn)WorkIF接口
*/
func (this *Person) Class() {println("Class")
}
func (this *Person) Income() {println("Income")
}//Person類自己的方法
func (this *Person) GetTest() {println("GetTest")
}func main() {p1 := Person{"張三", 18, "男"} //創(chuàng)建一個(gè)對(duì)象pIn := PersonIF(&p1) //實(shí)現(xiàn)接口pIn.Status() //調(diào)用接口的方法,接口無(wú)法調(diào)用類自己的方法,也就是無(wú)法調(diào)用GetTestpIn.Skills()p1.GetTest()fmt.Println(pIn)  //接口變量包含了接受實(shí)列的值和指向?qū)?yīng)方法表的指針,這里輸出的是實(shí)列的值
}

?? 接口也可以內(nèi)嵌接口

type PersonIF interface {Status()Skills()WorkIF
}type WorkIF interface {Class()Income()
}
func main() {p1 := Person{"張三", 18, "男"} //創(chuàng)建一個(gè)對(duì)象pIn := PersonIF(&p1)        //實(shí)現(xiàn)接口pIn.Class()			//可以調(diào)用嵌套接口中的實(shí)現(xiàn)fmt.Println(pIn)
}

2?? 接口類型斷言和空接口

?? Go語(yǔ)言有個(gè)萬(wàn)能的類型通配符,是一個(gè)空接口interfer{},因?yàn)樵?code>Go中任何接口類型都實(shí)現(xiàn)了空接口,類似于Java中的Object

?? 每個(gè)空接口變量在內(nèi)存中占據(jù)兩個(gè)字長(zhǎng),一個(gè)是用來(lái)存儲(chǔ)包含的類型,一個(gè)是存儲(chǔ)數(shù)據(jù)或者指向數(shù)據(jù)的指針

func main() {Test(1)Test("abc")Test(1.111)
}func Test(i interface{}) { //空類型fmt.Println(i)
}//輸出:
1
abc  
1.111
🌟 空接口實(shí)現(xiàn)存儲(chǔ)不同數(shù)據(jù)類型的切片/數(shù)組

?? 直接使用type給空接口一個(gè)別名類型,然后創(chuàng)建這個(gè)接口別名類型的切片/數(shù)組(真的太聰明了這個(gè)辦法)

package mainimport "fmt"type Empty interface{}type Vector struct {e []Empty
}func (this *Vector) NewInit() { //初始化切片this.e = make([]Empty, 5)
}func (this *Vector) Set(i int, a interface{}) { //將元素插入指定索引this.e[i] = a
}
func (this *Vector) Get(i int) { //獲取指定索引元素并輸出fmt.Println(this.e[i])
}func main() {var v Vectorv.NewInit() //初始化v.Set(0, 22) //整數(shù)v.Set(1, "222") //stringv.Set(2, 13.14) //float32v.Get(0)v.Get(1)v.Get(2)
}//輸出:
22
222
13.14
🌟 復(fù)制切片到空接口切片

?? 如果你需要將切片復(fù)制到一個(gè)空接口切片中需要通過(guò)for-range,不能直接傳遞

func main() {dataSlice := make([]int, 0)dataSlice = append(dataSlice, 1, 2, 3, 4, 5, 6)emptySlice := make([]interface{}, 10)for i, j := range dataSlice {emptySlice[i] = j}fmt.Println(emptySlice)
}

?? 一個(gè)接口的值是可以賦值給另外一個(gè)接口變量,只要底層類型實(shí)現(xiàn)了必要的方法

🌟 類型斷言

?? 如果變量是一個(gè)接口變量,則直接可以使用斷言機(jī)制,直接就是接口變量.(類型)即可,注意一定要是接口變量

func main() {Test(1)Test("abc")
}func Test(i interface{}) { //空類型if value, ok := i.(string); ok {fmt.Printf("值: %v 是string\n", value)} else {fmt.Printf("值: %v 不是string\n", i)}
}

?? 還有一種是type-switch

func main() {Test(1)Test("abc")
}func Test(i interface{}) { //空類型switch v := i.(type) {case string:fmt.Printf("值 %v 是string\n", v)case int:fmt.Printf("值 %v 是int\n", v)case float32:fmt.Printf("值 %v 是float32\n", v)default:fmt.Printf("我不想學(xué)習(xí)\n")}
}

反射

Go 語(yǔ)言反射的實(shí)現(xiàn)原理 | Go 語(yǔ)言設(shè)計(jì)與實(shí)現(xiàn) (draveness.me) 可以好好看看

?? Go語(yǔ)言的反射機(jī)制也是通過(guò)空接口來(lái)實(shí)現(xiàn)的,在reflect包中

?? 反射提供了兩個(gè)簡(jiǎn)單的函數(shù)實(shí)現(xiàn)一個(gè)是TypeOf(獲取類型信息),一個(gè)是ValueOf(獲取數(shù)據(jù)的運(yùn)行時(shí)表示)

它們兩個(gè)對(duì)應(yīng)了兩個(gè)不同的接口分別是TypeValue

golang-reflection

?? TypeOf返回的是一個(gè)Type接口對(duì)象,所以說(shuō)它可以使用Type方法

它接受一個(gè)any類型的值

type any = interface{} //空接口
// TypeOf函數(shù)返回給定參數(shù)i的類型。
// 
// 參數(shù):
// i - 任意類型的值。
// 
// 返回值:
// Type - 表示參數(shù)i類型的類型值。
func TypeOf(i any) Type {// 將i轉(zhuǎn)換為emptyInterface類型,以獲取其動(dòng)態(tài)類型信息。eface := *(*emptyInterface)(unsafe.Pointer(&i))// 使用noescape函數(shù)確保i的指針不會(huì)逃逸,這樣做是為了避免i的生命周期被延長(zhǎng)。// 這是基于Value.typ字段的注釋中提到的安全理由。return toType((*abi.Type)(noescape(unsafe.Pointer(eface.typ))))
}

?? 在Type接口中內(nèi)定義了很多方法

type Type interface {// 基本屬性Align() int           // 返回類型值對(duì)齊所需的字節(jié)數(shù)。FieldAlign() int      // 返回類型作為結(jié)構(gòu)體字段時(shí)的對(duì)齊要求。// 方法相關(guān)Method(int) Method    // 獲取方法集合中的第i個(gè)方法。NumMethod() int       // 返回方法總數(shù)。MethodByName(string) (Method, bool) // 通過(guò)名稱查找方法。// 類型基本信息Name() string        // 返回類型名。PkgPath() string     // 返回類型所在的包路徑。Size() uintptr       // 返回類型的大小。String() string      // 返回類型表示的字符串。Kind() Kind          // 返回類型的基本類別。// 類型兼容性Implements(Type) bool    // 檢查是否實(shí)現(xiàn)某個(gè)接口。AssignableTo(Type) bool // 檢查值是否可直接賦值給另一類型。ConvertibleTo(Type) bool // 檢查值是否可通過(guò)類型轉(zhuǎn)換匹配另一類型。Comparable() bool       // 指示類型值是否可比較。// 特定類型特有操作Elem() Type             // 對(duì)數(shù)組/切片/指針/映射/通道,返回元素類型。ChanDir() ChanDir        // 對(duì)通道類型,返回通信方向。IsVariadic() bool       // 對(duì)函數(shù)類型,檢查是否可變參數(shù)。Key() Type              // 對(duì)映射類型,返回鍵的類型。Len() int               // 對(duì)數(shù)組類型,返回其長(zhǎng)度。// 結(jié)構(gòu)體操作Field(int) StructField  // 獲取結(jié)構(gòu)體的第i個(gè)字段信息。NumField() int         // 返回結(jié)構(gòu)體字段數(shù)量。FieldByIndex([]int) StructField // 通過(guò)嵌套索引獲取字段信息。FieldByName(string) (StructField, bool) // 通過(guò)字段名獲取字段信息。FieldByNameFunc(func(string) bool) (StructField, bool) // 通過(guò)匹配函數(shù)查找字段。// 函數(shù)類型操作In(int) Type           // 獲取函數(shù)的第i個(gè)輸入?yún)?shù)類型。NumIn() int            // 返回函數(shù)輸入?yún)?shù)數(shù)量。Out(int) Type          // 獲取函數(shù)的第i個(gè)輸出參數(shù)類型。NumOut() int           // 返回函數(shù)輸出參數(shù)數(shù)量。// 內(nèi)部方法,用戶通常無(wú)需直接調(diào)用common(), uncommon() *internal // 返回底層實(shí)現(xiàn)相關(guān)的數(shù)據(jù)結(jié)構(gòu)。
}

?? ValueOf 放回一個(gè)Value對(duì)象,接受的也是一個(gè)任意類型的值

// ValueOf 是一個(gè)將任意類型轉(zhuǎn)換為 Value 類型的函數(shù)。
// 參數(shù) i 為任意類型的值,表示需要轉(zhuǎn)換的值。
// 返回值為 Value 類型,表示轉(zhuǎn)換后的值。
// 如果輸入值 i 為 nil,則返回一個(gè)空的 Value。
func ValueOf(i any) Value {// 檢查輸入值是否為 nil,如果是則返回空的 Valueif i == nil {return Value{}}// 如果滿足特定條件(go121noForceValueEscape 為 false),則標(biāo)記 i 為逃逸變量if !go121noForceValueEscape {escapes(i)}// 將輸入值 i 解包為 Value 類型并返回return unpackEface(i)
}

?? 在Value中也定義了一些方法,反射包中 reflect.Value 的類型與 reflect.Type 不同,它被聲明成了結(jié)構(gòu)體。這個(gè)結(jié)構(gòu)體沒(méi)有對(duì)外暴露的字段,但是提供了獲取或者寫(xiě)入數(shù)據(jù)的方法

type Value struct {// 內(nèi)部結(jié)構(gòu)未公開(kāi),實(shí)際包含值和類型等信息
}// 實(shí)例化Value的方法通常通過(guò)reflect.ValueOf或reflect零值的間接操作獲得// Kind 返回此Value所持有的值的類型種類。
func (v Value) Kind() Kind// Type 返回此Value所持有的值的具體類型信息。
func (v Value) Type() Type// Bool 獲取bool類型的值,如果Value不是bool類型則會(huì)panic。
func (v Value) Bool() bool// Int 獲取整數(shù)值,類型必須是整數(shù)類型,否則會(huì)panic。
func (v Value) Int() int64// Float 獲取浮點(diǎn)數(shù)值,類型必須是浮點(diǎn)數(shù)類型,否則會(huì)panic。
func (v Value) Float() float64// String 獲取字符串值,類型必須是string,否則會(huì)panic。
func (v Value) String() string// Interface 轉(zhuǎn)換Value為interface{}類型,幾乎所有類型都可以通過(guò)此方法獲取。
func (v Value) Interface() interface{}// Set 設(shè)置Value的值,新值必須是可設(shè)置的并且類型匹配。
func (v Value) Set(x Value) // SetBool 設(shè)置bool類型的值,Value必須是可設(shè)置的bool類型。
func (v Value) SetBool(x bool)// SetInt 設(shè)置整數(shù)值,Value必須是可設(shè)置的整數(shù)類型。
func (v Value) SetInt(x int64)// SetFloat 設(shè)置浮點(diǎn)數(shù)值,Value必須是可設(shè)置的浮點(diǎn)數(shù)類型。
func (v Value) SetFloat(x float64)// SetString 設(shè)置字符串值,Value必須是可設(shè)置的string類型。
func (v Value) SetString(x string)// Call 對(duì)于函數(shù)或方法Value,執(zhí)行調(diào)用并返回結(jié)果。
func (v Value) Call(in []Value) []Value// Elem 如果Value是一個(gè)指針,返回它指向的值的Value;否則返回自身。
func (v Value) Elem() Value// Field 獲取結(jié)構(gòu)體Value的第i個(gè)字段的Value。
func (v Value) Field(i int) Value// FieldByName 獲取結(jié)構(gòu)體Value的名為name的字段的Value。
func (v Value) FieldByName(name string) Value// Index 對(duì)于數(shù)組、slice或map的Value,返回索引i處的元素Value。
func (v Value) Index(i int) Value// MapIndex 對(duì)于map的Value,返回key對(duì)應(yīng)的元素Value。
func (v Value) MapIndex(key Value) Value// CanSet 返回此Value是否可被設(shè)置,即是否可以更改其底層值。
func (v Value) CanSet() bool// IsZero 判斷Value的底層值是否為零值。
func (v Value) IsZero() bool

?? Type方法實(shí)列

type Person struct {Name stringAge  intSex  string
}func (this *Person) toString() string {return fmt.Sprintf("Nmae: %v,Age: %v,Sex: %v", this.Name, this.Age, this.Sex)
}func main() {p1 := Person{"張三", 18, "男"}p1_demo := reflect.TypeOf(p1)             //獲取類型信息fmt.Println(p1_demo.Name())               //輸出類名fmt.Println(p1_demo.Size())               //輸出類型大小for i := 0; i < p1_demo.NumField(); i++ { //放回結(jié)構(gòu)體字段的個(gè)數(shù),然后輸出遍歷field := p1_demo.Field(i) //獲取字段fmt.Println(field.Name, field.Type, field.Offset)}for i := 0; i < p1_demo.NumMethod(); i++ { //放回結(jié)構(gòu)體方法的個(gè)數(shù),然后輸出遍歷method := p1_demo.Method(i) //獲取方法fmt.Println(method.Name, method.Type)}//數(shù)組p2 := [1]Person{Person{"張三", 18, "男"}}p2_demo := reflect.TypeOf(p2)fmt.Println(p2_demo.Len()) //輸出數(shù)組長(zhǎng)度}

?? Value方法實(shí)現(xiàn),可以使用ValueOf方法來(lái)修改值

package mainimport ("fmt""reflect"
)type Person struct {Name stringAge  intSex  string
}func main() {// 使用指針來(lái)確保可以通過(guò)反射修改值p1 := Person{"張三", 18, "男"}fmt.Println(p1)// 獲取p1的反射值p1_demo := reflect.ValueOf(&p1)// 由于p1是指針,我們先獲取其指向的值的反射值p1_val := p1_demo.Elem()// 檢查是否可以設(shè)置值if p1_val.CanSet() {// 創(chuàng)建一個(gè)新的Person值并通過(guò)反射設(shè)置newPerson := Person{"李四", 20, "女"}p1_val.Set(reflect.ValueOf(newPerson))} else {fmt.Println("無(wú)法設(shè)置值")}// 打印修改后的值fmt.Printf("%#v\n", p1)     // 使用%#v格式化輸出結(jié)構(gòu)體細(xì)節(jié)fmt.Println(p1_demo.Kind()) // 輸出類型信息
}

歡迎關(guān)注我,繼續(xù)探討技術(shù),如果覺(jué)得寫(xiě)的不錯(cuò)動(dòng)動(dòng)小手點(diǎn)個(gè)小贊,如果覺(jué)得我還有哪些不足可以私信哦

http://www.risenshineclean.com/news/50091.html

相關(guān)文章:

  • 淘寶客云建站官網(wǎng)百度q3財(cái)報(bào)2022
  • 做地產(chǎn)的設(shè)計(jì)網(wǎng)站seo顧問(wèn)
  • 政府網(wǎng)站用什么cmsseo新人怎么發(fā)外鏈
  • 長(zhǎng)沙外貿(mào)建站vue seo 優(yōu)化方案
  • 北京中高端網(wǎng)站建設(shè)友情鏈接買(mǎi)賣(mài)平臺(tái)
  • 網(wǎng)站免費(fèi)正能量不用下載歐洲站fba
  • 公司網(wǎng)站建設(shè)費(fèi)用賬務(wù)處理百度云群組
  • 深圳購(gòu)物網(wǎng)站建網(wǎng)站怎么快速排名
  • 圖片制作在線制作免費(fèi)seo外包公司費(fèi)用
  • 網(wǎng)站支付頁(yè)面怎么做的123網(wǎng)址之家
  • 常用的網(wǎng)站建設(shè)技術(shù)有什么軟件一鏈一網(wǎng)一平臺(tái)
  • 怎樣建立平臺(tái)愛(ài)站網(wǎng)seo
  • 建設(shè)營(yíng)銷(xiāo)網(wǎng)站要什么寧波技術(shù)好的企業(yè)網(wǎng)站制作
  • 中國(guó)歐洲陸運(yùn)專線外包seo公司
  • html 手機(jī)網(wǎng)站開(kāi)發(fā)吸引人的軟文標(biāo)題例子
  • wordpress theme 免費(fèi)北京搜索引擎優(yōu)化經(jīng)理
  • 可以做網(wǎng)站的編程有什么軟件成都網(wǎng)絡(luò)推廣優(yōu)化
  • PHP網(wǎng)站開(kāi)發(fā)程序員招聘免費(fèi)推廣產(chǎn)品的平臺(tái)
  • 網(wǎng)站產(chǎn)品頁(yè)面什么時(shí)候做怎么自己做網(wǎng)站
  • 網(wǎng)站被黑了怎么恢復(fù)重慶企業(yè)站seo
  • 大學(xué)二級(jí)學(xué)院網(wǎng)站建設(shè)必要性網(wǎng)站流量統(tǒng)計(jì)工具
  • 做php網(wǎng)站前端價(jià)格鄭州seo聯(lián)系搜點(diǎn)網(wǎng)絡(luò)效果好
  • 廣州哪里有學(xué)做網(wǎng)站的瀏覽器網(wǎng)站大全
  • 常寧市建設(shè)局網(wǎng)站seo培訓(xùn)
  • 北京建筑公司一覽表商品標(biāo)題關(guān)鍵詞優(yōu)化
  • 購(gòu)物 網(wǎng)站建設(shè)的市場(chǎng)分析電商廣告網(wǎng)絡(luò)推廣
  • 怎么看網(wǎng)站做沒(méi)做推廣手機(jī)軟文廣告300字
  • 婚慶公司網(wǎng)站模板seo公司排名教程
  • 天津武清網(wǎng)站建設(shè)廣州最新消息今天
  • 廣州文化網(wǎng)站模板百度手機(jī)助手下載安卓