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

當前位置: 首頁 > news >正文

培訓(xùn)的網(wǎng)站建設(shè)鳴蟬智能建站

培訓(xùn)的網(wǎng)站建設(shè),鳴蟬智能建站,動畫網(wǎng)站建設(shè),php網(wǎng)站開發(fā)實例教程案例方法 概述1. 方法定義2. 值方法、指針方法3. 方法集合 匿名字段表達式自定義 error 上一篇:延遲調(diào)用(defer) 概述 1. 方法定義 func (receiver T) 方法名(參數(shù)列表) (返回值列表){}receiver:接收者參數(shù)名T…

方法

  • 概述
    • 1. 方法定義
    • 2. 值方法、指針方法
    • 3. 方法集合
  • 匿名字段
  • 表達式
  • 自定義 error


上一篇:延遲調(diào)用(defer)


概述

1. 方法定義

 func (receiver T) 方法名(參數(shù)列表) (返回值列表){}receiver:接收者參數(shù)名T:方法所屬類型

Golang 方法總是綁定對象實例,并隱式地將實例作為第一實參(receiver)。

1. 只能為當前包內(nèi)(local)命名類型定義方法。
2. 參數(shù) receiver 可以任意命名;若方法中未使用,可省略參數(shù)名。
3. 參數(shù) receiver 類型可以是 T(值方法)或 *T(指針方法);基類型 T 不能是接口或指針。
4. 不支持方法重載,receiver 只是參數(shù)簽名的組成部分。
5. 可用實例 value(值)或 pointer(指針)調(diào)用全部方法,編譯器自動轉(zhuǎn)換。
package mainimport "fmt"type Person struct {name string
}// 定義指針方法(*T)
func (p *Person) SetName(name string) {p.name = name
}// 定義值方法(T)
func (p Person) GetName() string {return p.name
}func (p *Person) String() string {return fmt.Sprintf("Person: %s", p.name)
}// 1.只能為當前包內(nèi)命名類型定義方法
// 報錯:cannot define new methods on non-local type float64
func (f float64) Add(i, j float64) float64 {return i + j
}type Iter interface{}
// 3.receiver 類型不能是 poiter 或 interface
// 報錯 invalid receiver type iter (pointer or interface type)
func (Iter) SayType() {}func main() {p := Person{}   // 值類型(調(diào)用類型方法前,需要定義一個類型的值或指針)p.SetName("國慶") // 值類型調(diào)用指針方法fmt.Println(p.name)p2 := &p // 指針類型p.name = "國強"fmt.Println(p2.GetName()) // 指針類型調(diào)用值方法
}

2. 值方法、指針方法

  • 值方法 (接收者 receiver 是一個值,而非指針)

    該方法操作對應(yīng) receiver 的值的副本,即時使用了指針調(diào)用方法,但方法的接受者是值類型,所以方法內(nèi)部操作還是對副本的操作,而不是指針操作。

    package mainimport ("fmt"
    )type Person struct {name string
    }// 指針方法
    func (p *Person) SetName(name string) {fmt.Printf("指針 - addr: %p, %T\n", p, p)p.name = name
    }// 值方法
    func (p Person) SetNameByValue(name string) {fmt.Printf("值: %p, %T \n", &p, p)p.name = name
    }func main() {p := &Person{"中華"}		// 指針值fmt.Printf("P addr: %p, \n\n", p)  p.SetNameByValue("華夏")   // 調(diào)用值方法// p.name = 中華,并未改變,說明 p.SetNameByValue 復(fù)制了 p 的副本進行操作。fmt.Printf("name = %s\n\n", p.name)p.SetName("國慶")fmt.Printf("name = %s\n", p.name)   //  name = 國慶
    } 
    

    以上代碼輸出如下,可以看出:

    • p.SetName(指針方法)中 p 的地址和 main 中 p 的地址相同,為同一變量,且該方法給 p.name 重新賦值后,main 中 p.name 跟著改變。
    • p.SetNameByValue(值方法)中 p 的地址和 main 中 p 的地址不同,且調(diào)用該方法給 p.name 重新賦值后,main 中 p.name 并未改變。
    P addr: 0xc000024070,值: 0xc000024080, test.Person
    name = 中華指針 - addr: 0xc000024070, *test.Person
    name = 國慶
    
  • 指針方法(接收者 receiver 是一個指針)

    與值方法相反,當接受者是指針時,即使用值類型調(diào)用那么方法內(nèi)部也是對指針的操作。

    func main() {p := Person{"中華"}		// 值類型fmt.Printf("P addr: %p, \n\n", p)  p.SetNameByValue("華夏")fmt.Printf("name = %s\n\n", p.name) // name = 中華p.SetName("國慶")// 即時 p 為值類型,調(diào)用指針類型時,指針方法內(nèi)部也是對指針操作。fmt.Printf("name = %s\n", p.name)   //  name = 國慶
    } 
    
  • 方法與函數(shù)

    • 方法可以看做一種特殊(特定類型變量)的函數(shù)。

      文章開頭講過,方法總是綁定對象實例,并隱式地將實例作為第一實參 receiver。

      func (p *Person) SetName(name string) {}
      等同于
      func SetName(p *Person, name string) { }

    • 方法與函數(shù)的區(qū)別

      • 函數(shù)不屬于任何類型,而方法屬于特定的類型變量(receiver)的函數(shù)。
      • 接收者 receiver 無論是值類型或指針類型,都可以調(diào)用全部方法。但函數(shù)中,參數(shù)類型為值類型,則只能將值類型作為參數(shù)傳遞;參數(shù)類型為指針,則只能將指針類型作為參數(shù)傳遞。
    type Person struct {name string
    }// 指針方法
    func (p *Person) SetName(name string) {p.name = name
    }
    // 該函數(shù)與方法 p.SetName 相同 
    func SetName(p *Person, name string) {p.name = name
    }// 值方法
    func (p Person) GetName() {return p.name
    }
    // 該函數(shù)與方法 p.GetName 相同
    func GetName(p Person) string {return p.name
    }func main() {p := Person{}// 接收者 p 為值類型,可以調(diào)用指針類型方法。反之亦然。p.SetName("中國") fmt.Println(p.GetName())// 函數(shù)中,參數(shù)為指針類型,只能以指針類型作為參數(shù),反之同理。SetName(&p, "華夏") fmt.Println(p.GetName())fmt.Println(p.GetName(), GetName(p))
    }
    

3. 方法集合

每個類型都有與之關(guān)聯(lián)的方法集,這會影響到接口實現(xiàn)規(guī)則。
  • 一個類型的值類型的方法集合中僅包含它的所有值方法:類型 T 方法集包含全部 receiver T 方法。
  • 一個類型的指針類型的方法集合囊括了所有值方法和所有指針方法:類型 *T 方法集包含全部 receiver T + *T 方法。
func main() {p := Person{} // 值類型m := reflect.TypeOf(p)for i := 0; i < m.NumMethod(); i++ {method := m.Method(i)fmt.Println("Value Method:", method.Name, method.Type)}p2 := &Person{} // 指針類型m = reflect.TypeOf(p2)for i := 0; i < m.NumMethod(); i++ {method := m.Method(i)fmt.Println("Pointer Method:", method.Name, method.Type)}
}

輸出:

Value Method: GetName func(test.Person) string
Pointer Method: GetName func(*test.Person) string
Pointer Method: SetName func(*test.Person, string)
Pointer Method: String func(*test.Person) string

匿名字段

參考結(jié)構(gòu)體章節(jié):8.結(jié)構(gòu)體匿名字段

Golang 中,類型的成員字段在聲明時沒有字段名而只有類型,那么它就是一個嵌入字段,也可以被稱為匿名字段。

  • 匿名字段默認采用類型作為字段名,要求字段名稱必須唯一,且一個類型中同種類型的匿名字段只能有一個。

  • 任何類型都可以作為匿名字段。

  • 匿名結(jié)構(gòu)體成員可直接訪問;當多個匿名結(jié)構(gòu)體內(nèi)存在相同字段時,為了避免歧義需要指定具體的內(nèi)嵌結(jié)構(gòu)體的字段。

  • 推薦使用匿名方式嵌套結(jié)構(gòu)體。

  • 通過匿名字段可以實現(xiàn)繼承,實現(xiàn)“override”。

  • 不可遞歸循環(huán)嵌套(你中有我,我中有你)。

表達式

package mainimport "fmt"type Person struct {name string
}func (p *Person) SetName(name string) {p.name = name
}func (p Person) SetNameByValue(name string) {p.name = name
}func (p Person) GetName() string {return p.name
}func main() {p := Person{"Tom"}fmt.Println(p.GetName()) // 直接調(diào)用mVal := p.GetName         // 隱式傳遞,此時復(fù)制了pmExp := (*Person).GetName // 顯式傳遞p.SetName("Jerry")fmt.Println(mVal(), mExp(&p), p.GetName()) // Tom Jerry JerrymExp2 := (*Person).SetNameByValue // 值方法,此時依然會復(fù)制 pmExp2(&p, "Lucy")fmt.Println(mExp(&p), p.GetName()) // Jerry JerrymExp3 := (*Person).SetNamemExp3(&p, "Lucy")fmt.Println(mExp(&p), p.GetName()) // Lucy Lucy
}

自定義 error

package mainimport ("fmt""os""time"
)type CustomError struct {path       stringop         stringcreateTime stringmessage    string
}func (e *CustomError) Error() string {return fmt.Sprintf("%s %s %s: %s", e.createTime, e.op, e.path, e.message)
}func newError(path, op, msg string) *CustomError {return &CustomError{path:       path,op:         op,createTime: time.Now().Format("2006-01-02 15:04:05"),message:    msg,}
}func Open(fname string) (err error) {f, err := os.Open(fname)if err != nil {err = newError(fname, "open", err.Error())return}defer func() {if f.Close() != nil {err = newError(fname, "close", err.Error())}}()return nil
}func main() {err := Open("./test/test.txt")fmt.Println(err)
}
http://www.risenshineclean.com/news/47398.html

相關(guān)文章:

  • 怎樣看出一個網(wǎng)站是那個公司做的合肥百度推廣公司哪家好
  • 鄭州網(wǎng)站設(shè)計專家seo掛機賺錢
  • 北京國貿(mào)網(wǎng)站建設(shè)網(wǎng)絡(luò)優(yōu)化器下載
  • 網(wǎng)站制作公司承擔seo外包公司多嗎
  • 網(wǎng)站加關(guān)鍵詞代碼培訓(xùn)網(wǎng)站建設(shè)
  • 仿網(wǎng)站制作教學(xué)視頻網(wǎng)絡(luò)營銷與直播電商怎么樣
  • 四川成都營銷型網(wǎng)站數(shù)據(jù)分析網(wǎng)站
  • 網(wǎng)站建設(shè) 后端前端廣告聯(lián)盟平臺哪個好
  • jsp是前端還是后端開發(fā)的煙臺seo網(wǎng)絡(luò)推廣
  • 在華圖做網(wǎng)站編輯友情鏈接交換條件
  • 百度收錄網(wǎng)站定位地址公司網(wǎng)絡(luò)推廣營銷
  • 網(wǎng)站開發(fā)需要什么資質(zhì)百度官方網(wǎng)頁版
  • 怎么健手機網(wǎng)站最新新聞熱點事件及評論
  • 彈性云主機做網(wǎng)站營銷策略范文
  • 論壇網(wǎng)站建設(shè)網(wǎng)站推廣的方法有哪幾種
  • 現(xiàn)在購物平臺哪個最好seo黑帽培訓(xùn)
  • 網(wǎng)站建設(shè)策劃案怎么寫推廣普通話手抄報文字內(nèi)容
  • 建官方網(wǎng)站的公司網(wǎng)推公司
  • 現(xiàn)貨投資網(wǎng)站建設(shè)楓樹seo網(wǎng)
  • 松江手機網(wǎng)站建設(shè)上海關(guān)鍵詞seo
  • 紅色主題網(wǎng)站模板seo網(wǎng)站內(nèi)部優(yōu)化
  • 水資源監(jiān)控能力建設(shè) 網(wǎng)站搜狗整站優(yōu)化
  • 手機網(wǎng)站導(dǎo)航設(shè)計模板seo網(wǎng)站關(guān)鍵詞優(yōu)化費用
  • 湖南長沙網(wǎng)站制作關(guān)鍵詞優(yōu)化排名怎么做
  • 合肥做網(wǎng)站建設(shè)中國站長之家域名查詢
  • 安卓app制作開發(fā)網(wǎng)站推廣優(yōu)化教程
  • 網(wǎng)站建設(shè)編寫代碼問題人工智能教育培訓(xùn)機構(gòu)排名
  • 網(wǎng)站資訊建設(shè)考研培訓(xùn)
  • 如何建立一個購物網(wǎng)站播放量自助下單平臺
  • 西峰住房和城鄉(xiāng)建設(shè)局網(wǎng)站怎么建網(wǎng)站平臺賣東西