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

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

網(wǎng)站備案截圖網(wǎng)站收錄免費(fèi)咨詢(xún)

網(wǎng)站備案截圖,網(wǎng)站收錄免費(fèi)咨詢(xún),西安電子科技大學(xué)信息化建設(shè)處網(wǎng)站,可靠的機(jī)票網(wǎng)站建設(shè)目錄 4. struct 結(jié)構(gòu)體4.1 初始化4.2 內(nèi)嵌字段4.3 可見(jiàn)性4.4 方法與函數(shù)4.4.1 區(qū)別4.4.2 閉包 4.5 Tag 字段標(biāo)簽4.5.1定義4.5.2 Tag規(guī)范4.5.3 Tag意義 4. struct 結(jié)構(gòu)體 go的結(jié)構(gòu)體類(lèi)似于其他語(yǔ)言中的class,主要區(qū)別就是go的結(jié)構(gòu)體沒(méi)有繼承這一概念,但可…

目錄

  • 4. struct 結(jié)構(gòu)體
    • 4.1 初始化
    • 4.2 內(nèi)嵌字段
    • 4.3 可見(jiàn)性
    • 4.4 方法與函數(shù)
      • 4.4.1 區(qū)別
      • 4.4.2 閉包
    • 4.5 Tag 字段標(biāo)簽
      • 4.5.1定義
      • 4.5.2 Tag規(guī)范
      • 4.5.3 Tag意義

4. struct 結(jié)構(gòu)體

go的結(jié)構(gòu)體類(lèi)似于其他語(yǔ)言中的class,主要區(qū)別就是go的結(jié)構(gòu)體沒(méi)有繼承這一概念,但可以使用類(lèi)型嵌入來(lái)實(shí)現(xiàn)相似功能。

4.1 初始化

使用type關(guān)鍵字來(lái)定義一個(gè)新的類(lèi)型,struct將新類(lèi)型限定為結(jié)構(gòu)體類(lèi)型。

結(jié)構(gòu)體中的字段可以為任何類(lèi)型,但是包含一些特殊類(lèi)型 如:接口,管道,函數(shù),指針的時(shí)候要格外注意

//type定義一個(gè)新類(lèi)型
type newInt int//type定義一個(gè)簡(jiǎn)單的結(jié)構(gòu)體
type base struct{value int   
}//type定義一個(gè)復(fù)雜的結(jié)構(gòu)體
type student struct {Name stringage  intc    interface{}d    func() inte    func()base     //將base類(lèi)型嵌入到了student類(lèi)型中
}

4.2 內(nèi)嵌字段

內(nèi)嵌字段大體上有兩種方式:顯式指定(m1)和隱式指定(m2)

  • 顯式指定就相當(dāng)于把目標(biāo)結(jié)構(gòu)體當(dāng)作字段,調(diào)用時(shí)需要先調(diào)用這個(gè)字段,在調(diào)用目標(biāo)結(jié)構(gòu)體中的信息
  • 隱式指定相當(dāng)于把目標(biāo)結(jié)構(gòu)體中的所有字段都在新結(jié)構(gòu)體中創(chuàng)建了一次,并且指向嵌入結(jié)構(gòu)體內(nèi)部。同時(shí)創(chuàng)建同名嵌入結(jié)構(gòu)體對(duì)象[指與base同名]
  • 顯式創(chuàng)建同名結(jié)構(gòu)體字段 ≠ 隱式指定
type base struct {Value int
}
//顯式指定
type m1 struct {b base
}//隱式指定
type m2 struct {base
}//顯式指定同名字段
type m3 struct {base base
}

對(duì)上述結(jié)構(gòu)體進(jìn)行調(diào)用:

  • 只有隱式指定直接操作被嵌入結(jié)構(gòu)體內(nèi)的數(shù)據(jù);
  • 隱式指定后,直接操作嵌入結(jié)構(gòu)體中的數(shù)據(jù)和通同名結(jié)構(gòu)體操作作用一樣
func main() {a1 := m1{}a2 := m2{}a3 := m3{}//顯式指定只能通過(guò)嵌入結(jié)構(gòu)體進(jìn)行操作// a1.Value = 1 //a1.Value undefined (type m2 has no field or method Value)a1.b.Value = 2//隱式指定兩種操作數(shù)據(jù)方法操作的是同一個(gè)變量a2.Value = 2a2.base.Value = 3fmt.Println(a2.Value) //3//顯式指定同名變量 ≠ 隱式指定 // a3.Value = 3 //a3.Value undefined (type m3 has no field or method Value)a3.base.Value = 4
}

當(dāng)內(nèi)嵌字段中的字段與結(jié)構(gòu)體中得字段同名時(shí):

  • 直接調(diào)用時(shí)是指定當(dāng)前結(jié)構(gòu)體中顯式定義的字段,但嵌入結(jié)構(gòu)體中的字段仍可通過(guò)嵌入類(lèi)型進(jìn)行調(diào)用
  • 方法同理
//數(shù)據(jù)
func main() {a1 := m1{}a1.Value = "hello world"a1.base.Value = 1fmt.Println(a1)//獲取a1中的所有字段類(lèi)型t := reflect.TypeOf(a1)for i := 0; i < t.NumField(); i++ {field := t.Field(i)fieldType := field.Typefmt.Printf("Field: %s, Type: %s\n", field.Name, fieldType.Name())}
}type base struct {Value int
}type m1 struct {Value stringbase
}
/*
{hello world {1}}
Field: Value, Type: string
Field: base, Type: base*/
//方法
func main() {a1 := m1{}a1.test()a1.base.test()fmt.Println(a1)//獲取a1中的所有字段類(lèi)型t := reflect.TypeOf(a1)for i := 0; i < t.NumField(); i++ {field := t.Field(i)fieldType := field.Typefmt.Printf("Field: %s, Type: %s\n", field.Name, fieldType.Name())}
}type base struct {Value int
}func (b *base) test() {b.Value = 1
}
func (m *m1) test() {m.Value = "hello world"
}type m1 struct {Value stringbase
}
/*
{hello world {1}}
Field: Value, Type: string
Field: base, Type: base*/

4.3 可見(jiàn)性

  • 首字母大寫(xiě)表示該字段/方法/結(jié)構(gòu)體為可導(dǎo)出的,反之為不可導(dǎo)出的
  • 在同一個(gè)包內(nèi),不區(qū)分是否可導(dǎo)出,都可訪(fǎng)問(wèn);包外只能訪(fǎng)問(wèn)可導(dǎo)出的字段/方法/結(jié)構(gòu)體
  • 不可導(dǎo)出的字段不可以進(jìn)行序列化(轉(zhuǎn)化為json)
  • 可通過(guò)可導(dǎo)出的方法去操作不可導(dǎo)出的字段
// test/test1.go
package testtype User struct {Name stringage  int
}func (u *User) Test() {u.Name = "hello"u.age = 18
}func (u *User) test() {u.Name = "world"u.age = 81
}type student struct {Name stringage  int
}
//main.go
package mainimport ("fmt""test/test"
)func main() {a := test.User{}//b := test.student{} // 不能在包外訪(fǎng)問(wèn)未導(dǎo)出結(jié)構(gòu)體a.Name = "123"//a.age = 123 // 不能在包外訪(fǎng)問(wèn)未導(dǎo)出字段a.Test()//a.test() // 不能在包外訪(fǎng)問(wèn)未導(dǎo)出方法fmt.Println(a)/*{hello 18}*/
}

4.4 方法與函數(shù)

4.4.1 區(qū)別

  • 方法定義是必須有一個(gè)接收器(receiver);函數(shù)不需要
  • 大部分情況下,方法的調(diào)用需要有一個(gè)對(duì)象;函數(shù)不需要
  • 由于go中的所有傳遞都是值傳遞,也就是將數(shù)據(jù)復(fù)制一份再調(diào)用,所以如果想要修改原本對(duì)象的值,就要傳遞指針,進(jìn)行引用傳遞
func 函數(shù)名 (參數(shù)) 返回值類(lèi)型 {函數(shù)體} //函數(shù)定義
func (接收器) 方法名  (參數(shù)) 返回值類(lèi)型 {函數(shù)體} // 方法定義
func main() {a := User{}a.setName() // 方法調(diào)用fmt.Println(a)setName(&a) // 函數(shù)調(diào)用fmt.Println(a)
}
/*{world 0}{hello 0}*/type User struct {Name stringage  int
}
//函數(shù)
func setName(u *User) {u.Name = "hello"
}
//方法
func (u *User) setName() {u.Name = "world"
}

值傳遞時(shí)可以通過(guò)返回值的方式修改目標(biāo)對(duì)象

func main() {a := User{}a = a.setName() //需要顯式給原變量賦值fmt.Println(a)a = setName(a)  //需要顯式給原變量賦值fmt.Println(a)
}type User struct {Name stringage  int
}func setName(u User) User {u.Name = "hello"return u
}
func (u User) setName() User {u.Name = "world"return u
}

4.4.2 閉包

說(shuō)到函數(shù)和方法,就必須說(shuō)一下閉包

什么是閉包?

簡(jiǎn)單來(lái)說(shuō),就是函數(shù)內(nèi)部引用函數(shù)外部變量,導(dǎo)致變量生命周期發(fā)生變化。這樣的函數(shù)就叫做閉包

常見(jiàn)于函數(shù)返回值為另一個(gè)函數(shù)時(shí)

package mainimport "fmt"func main() {b := test()fmt.Println(b())fmt.Println(b())
}func test() func() int {a := 1return func() int {a++return a}
}

上面的函數(shù)導(dǎo)致變量a無(wú)法正常釋放,導(dǎo)致變量逃逸

go build -gcflags="-m" main.go
# command-line-arguments
./main.go:11:6: can inline test
./main.go:13:9: can inline test.func1
./main.go:6:11: inlining call to test
./main.go:13:9: can inline main.test.func1
./main.go:7:15: inlining call to main.test.func1
./main.go:7:13: inlining call to fmt.Println
./main.go:8:15: inlining call to main.test.func1
./main.go:8:13: inlining call to fmt.Println
./main.go:6:11: func literal does not escape
./main.go:7:13: ... argument does not escape
./main.go:7:15: ~R0 escapes to heap
./main.go:8:13: ... argument does not escape
./main.go:8:15: ~R0 escapes to heap
./main.go:12:2: moved to heap: a
./main.go:13:9: func literal escapes to heap

4.5 Tag 字段標(biāo)簽

4.5.1定義

在reflect包中提供了獲取字段名稱(chēng)、類(lèi)型、Tag的方法(上文展示過(guò)獲取名稱(chēng)和類(lèi)型)

結(jié)構(gòu)體StructField表示結(jié)構(gòu)體的一個(gè)字段(reflect/type.go)

// A StructField describes a single field in a struct.
type StructField struct {// Name is the field name.Name string// PkgPath is the package path that qualifies a lower case (unexported)// field name. It is empty for upper case (exported) field names.// See https://golang.org/ref/spec#Uniqueness_of_identifiersPkgPath stringType      Type      // field typeTag       StructTag // field tag stringOffset    uintptr   // offset within struct, in bytesIndex     []int     // index sequence for Type.FieldByIndexAnonymous bool      // is an embedded field
}type StructTag string 

4.5.2 Tag規(guī)范

StructTag本質(zhì)上就是字符串,理論上任何形式都符合規(guī)范。但通常情況下約定,Tag的格式應(yīng)該是key:“value”

  • key:非空字符串,不能包含控制字符,空格,引號(hào),冒號(hào)
  • value:雙引號(hào)包圍的字符串
  • 冒號(hào)前后不能有空格,多個(gè)value用逗號(hào)隔開(kāi),key之間用空格隔開(kāi)
  • key一般表示用途,value表示控制指令;

4.5.3 Tag意義

  • Go語(yǔ)言反射機(jī)制可以給結(jié)構(gòu)體成員賦值,用Tag可以決定賦值的動(dòng)作
  • 可以使用定義好的Tag規(guī)則,參考規(guī)則就可以繼續(xù)不同的操作
//僅對(duì)Tag值為true的字段賦值(Tag決定賦值動(dòng)作)
type Person struct {Name string `assign:"true"`Age  int    `assign:"false"`
}func assignValues(v interface{}) {val := reflect.ValueOf(v).Elem() // 獲取指針指向的值typ := val.Type()for i := 0; i < val.NumField(); i++ {field := val.Field(i)tag := typ.Field(i).Tag.Get("assign") // 獲取字段的tagif tag == "true" {// 根據(jù)字段類(lèi)型賦值switch field.Kind() {case reflect.String:field.SetString("Default Name")case reflect.Int:field.SetInt(25)}}}
}func main() {p := &Person{}assignValues(p)fmt.Printf("Person: %+v\n", p)
}
/*
Person: &{Name:Default Name Age:0}*/

下方例子使用了json:“kind,omitempty”,這個(gè)tag規(guī)定了字段為空不進(jìn)行序列化;

import ("encoding/json""fmt"
)type Person struct {Name  string `json:"kind,omitempty"` //為空時(shí)不進(jìn)行序列化Value intage   int
}func main() {// 創(chuàng)建一個(gè) Person 實(shí)例p := Person{Name: "", Value: 100, age: 100}// 序列化為 JSONjsonData, _ := json.Marshal(p)fmt.Println(string(jsonData)) /*{"Value":100}*/
}
http://www.risenshineclean.com/news/38527.html

相關(guān)文章:

  • 克隆網(wǎng)站后怎么做查詢(xún)關(guān)鍵詞網(wǎng)站
  • 銀川app購(gòu)物網(wǎng)站制作公司西安網(wǎng)站搭建公司
  • 專(zhuān)業(yè)網(wǎng)站設(shè)計(jì)公司哪家好百度投訴中心人工電話(huà)號(hào)碼
  • .net網(wǎng)站開(kāi)發(fā)實(shí)例臨沂seo代理商
  • 做黃色網(wǎng)站被抓了怎么處理公司培訓(xùn)課程有哪些
  • 天龍八部私服怎么做網(wǎng)站百度風(fēng)云排行榜
  • 蘇州做網(wǎng)站推廣哪家好網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃書(shū)論文
  • 專(zhuān)做動(dòng)漫av的網(wǎng)站市場(chǎng)營(yíng)銷(xiāo)
  • 網(wǎng)站建設(shè)方向百度搜索風(fēng)云榜總榜
  • 廣州企業(yè)推廣seo工資待遇 seo工資多少
  • 有沒(méi)有做維修的網(wǎng)站哪有免費(fèi)的網(wǎng)站
  • 網(wǎng)站收縮欄免費(fèi)自助建站網(wǎng)站
  • 手機(jī)站建網(wǎng)站免費(fèi)
  • 有什么做兼職的網(wǎng)站關(guān)鍵詞長(zhǎng)尾詞優(yōu)化
  • 下載簡(jiǎn)歷模板免費(fèi)百度系優(yōu)化
  • html5效果網(wǎng)站做一個(gè)網(wǎng)站要花多少錢(qián)
  • 群站優(yōu)化之鏈輪模式制作網(wǎng)站要花多少錢(qián)
  • 做網(wǎng)站要用到數(shù)據(jù)庫(kù)嗎新東方考研班收費(fèi)價(jià)格表
  • 廣州低價(jià)網(wǎng)站建設(shè)黃頁(yè)88
  • 有了域名和空間怎么做網(wǎng)站市場(chǎng)營(yíng)銷(xiāo)的策劃方案
  • 網(wǎng)站建設(shè)術(shù)語(yǔ)解釋在線(xiàn)crm
  • 規(guī)避電子政務(wù)門(mén)戶(hù)網(wǎng)站建設(shè)的教訓(xùn)優(yōu)秀網(wǎng)頁(yè)設(shè)計(jì)賞析
  • 關(guān)于seo網(wǎng)站優(yōu)化公司黑馬培訓(xùn)機(jī)構(gòu)可靠嗎
  • 贛縣網(wǎng)站建設(shè)國(guó)內(nèi)新聞最新消息十條
  • h5開(kāi)發(fā)教程哈爾濱seo網(wǎng)站管理
  • 做網(wǎng)站賺錢(qián)的時(shí)代過(guò)去了嗎百度地圖導(dǎo)航
  • 網(wǎng)站設(shè)置默認(rèn)首頁(yè)網(wǎng)絡(luò)營(yíng)銷(xiāo)網(wǎng)
  • 萬(wàn)戶(hù)網(wǎng)站免費(fèi)手游推廣平臺(tái)
  • 杭州國(guó)外網(wǎng)站推廣公司站長(zhǎng)之家 站長(zhǎng)工具
  • 網(wǎng)站開(kāi)發(fā)與實(shí)訓(xùn)報(bào)告企業(yè)優(yōu)化推廣