Go-再論struct

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

簡介

在Go-Structure對struct做了簡單的介紹,本文參考如下書目繼續豐富本專題。

  • 《Web Development with Go》 Chapter 3
  • 《The Go Programming Language》4.4 Page99

pointer and nonpointer method receiver

在Go-Structure一文給出的範例程式碼中,使用的都是pointer receiver。事實上,也可以使用nonpointer receiver。事實上,也可以使用nonpointer

樣本:

package main import (    "fmt")type Point struct {    x, y int }func (p Point) GetX() int {    return p.x}func (p Point) GetY() int {    return p.y}func (p *Point) SetX(ix int) {    (*p).x = ix}func (p *Point) SetY(iy int) {    (*p).y = iy}func (p *Point) SetY2(iy int) {    p.y = iy}func (p Point) SetY3(iy int) {    p.y = iy}func test1() {    p := Point{1, 2}    fmt.Print(p, "\t")    fmt.Print("x=", p.GetX(), "\t")    fmt.Print("y=", p.GetY(), "\t")    p.SetX(3)    p.SetY(4)    fmt.Print(p, "\t")    (&p).SetX(5)    (&p).SetY(6)    fmt.Print(p, "\t")    fmt.Println()}// SetY() -> SetY2()func test2() {    p := Point{1, 2}    fmt.Print(p, "\t")    fmt.Print("x=", p.GetX(), "\t")    fmt.Print("y=", p.GetY(), "\t")    p.SetX(3)    p.SetY2(4)    fmt.Print(p, "\t")    (&p).SetX(5)    (&p).SetY2(6)    fmt.Print(p, "\t")    fmt.Println()}// SetY() -> SetY3()func test3() {    p := Point{1, 2}    fmt.Print(p, "\t")    fmt.Print("x=", p.GetX(), "\t")    fmt.Print("y=", p.GetY(), "\t")    p.SetX(3)    p.SetY3(4)    fmt.Print(p, "\t")    (&p).SetX(5)    (&p).SetY3(6)    fmt.Print(p, "\t")    fmt.Println()}func test4() {    p := &Point{1, 2}    fmt.Print(p, "\t")    fmt.Print("x=", p.GetX(), "\t")    fmt.Print("y=", p.GetY(), "\t")    p.SetX(3)    p.SetY(4)    fmt.Print(p, "\t")    //calling method SetX with receiver &p (type **Point) requires explicit dereference    //(&p).SetX(5)    //(&p).SetY(6)    //fmt.Print(p, "\t")    fmt.Println()}/*D:\examples>go run helloworld.gotest1: {1 2}    x=1     y=2     {3 4}   {5 6}test2: {1 2}    x=1     y=2     {3 4}   {5 6}test3: {1 2}    x=1     y=2     {3 2}   {5 2}test4: &{1 2}   x=1     y=2     &{3 4}D:\examples>*/func main() {    fmt.Print("test1: ")    test1()    fmt.Print("test2: ")    test2()    fmt.Print("test3: ")    test3()    fmt.Print("test4: ")    test4()}

要點

copied from:《Web Development with Go》 Chapter 3, Page 39

If you want to modify the data of a receiver from the method, the receiver must be a pointer

If the struct has a pointer receiver on some its methods, it is better to use it for the rest of the methods because it enables better consistency and predictability for the struct behaviors.

pointer & dot notation

這裡再介紹指標類型和.操作符的特殊意義。在前面的例子中,有如下代碼:

func (p *Point) SetY2(iy int) {    p.y = iy}

其等價於:

func (p *Point) SetY2(iy int) {    (*p).y = iy}

這種文法是Go中非常特殊的一點。這種文法的證據源於《The Go Programming Language》4.4 Page 100,代碼如下:

type Employee struct {    ID        int    Name      string    Address   string    DoB       time.Time    Position  string    Salary    int    ManagerID int}

The dot notation also works with a pointer to a struct:

var employeeOfTheMonth *Employee = &dilbertemployeeOfTheMonth.Position += " (proactive team player)"

The last statement is equivalent to

(*employeeOfTheMonth).Position += " (proactive team player)"

Go指標的這種文法可以簡化代碼。

結構自嵌套

一個結構S內部不能有S成員,但可以有指向S的成員(指標 *S).

type tree struct {    value int    left, right *tree}

比較結構體對象

Go中不能重載==操作符,對於要比較(同一種)結構體的兩個對象,則要求其每個field都是可以比較的。而且在比較的時候,是按照每個field依次比較。也可以自訂比較的函數,比如Equals()。

package main import (    "fmt")type Point struct {    x, y int }func (p Point) GetX() int {    return p.x}func (p Point) GetY() int {    return p.y}func (p *Point) SetX(ix int) {    p.x = ix}func (p *Point) SetY(iy int) {    p.y = iy}func (p *Point) Equals(point Point) bool {    return p.x == point.x}func Equals(p1 Point, p2 Point) bool {    return p1.x == p2.x}func main() {    p1 := Point{1, 2}    p2 := Point{x:1, y:2}    p3 := Point{1, 3}    fmt.Println(p1 == p2, p2 == p3) // true, false    fmt.Println(p1.x == p2.x && p1.y == p2.y) // true. Equals to "p1 == p2"    fmt.Println(p1.Equals(p3)) // true    fmt.Println(Equals(p2, p3)) // true}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.