Go Language method Detailed _golang

Source: Internet
Author: User
Tags anonymous string format

In the first two chapters we introduce functions and struct, do you ever think of a function as a struct field? Today we'll explain another form of function, with a function of the receiver, which we call method

Method

Now suppose there is a scene where you define a struct called a rectangle, and you want to compute his area now, then we should do it in the following way

Copy Code code as follows:

Package Main
Import "FMT"

Type Rectangle struct {
width, height float64
}

Func area (r Rectangle) float64 {
Return R.width*r.height
}

Func Main () {
R1: = rectangle{12, 2}
R2: = rectangle{9, 4}
Fmt. Println ("area of R1 are:", area (R1))
Fmt. Println ("area of R2 are:", area (R2))
}

This code can calculate the size of the rectangle, but area () is not implemented as a rectangle method (similar to the object-oriented method), but rather the rectangle object (such as R1,R2) is passed as a parameter to compute the area of the function.

This implementation of course no problem, but when you need to increase the circle, square, Pentagon and even other polygons, when you want to calculate their size? Then you can only add new functions, but you have to change the function name, become area_rectangle, area_circle, Area_triangle ...

As the following illustration shows, ellipses represent functions, and these functions do not belong to struct (or, in object-oriented terms, not Class), they exist separately in the struct periphery, rather than in the concept of a struct.

Figure 2.8 Diagram of method and struct

Obviously, such an implementation is not elegant, and conceptually "area" is a property of the shape, which belongs to this particular shape, like the length and width of a rectangle.

Based on the above reasons, there is the concept of method, which is attached to a given type, and his syntax is almost the same as that of the function, but adds a receiver (i.e. the subject that method is compliant with) after Func.

In the case of the shape mentioned above, method area () is dependent on a shape (for example, rectangle) to function. The Rectangle.area () is emitted by Rectangle, and area () is a Rectangle method, not a peripheral function.

More specifically, Rectangle has field length and width, and method area (), and these fields and methods belong to rectangle.

In the words of Rob Pike:

Copy Code code as follows:

"A" is the a function with an implicit-a-argument, called a receiver.

The syntax for method is as follows:

Copy Code code as follows:

Func (R receivertype) funcName (parameters) (results)

Here we use the first example with method:

Copy Code code as follows:

Package main
Import (
    "FMT"
  & nbsp "Math"
)

Type Rectangle struct {
    width, height float64
}

Type Circ Le struct {
    radius float64
}

Func (R Rectangle) area () float64 {
    ; Return R.width*r.height
}

Func (c Circle) area () float64 {
    return C.radius * C.radius * Math. Pi
}


Func main () {
    r1: = rectangle{12, 2}
    r2: = rectangle{ 9, 4}
    c1: = circle{10}
    c2: = circle{25}

    fmt. Println ("Area of R1 is:", R1.area ())
    FMT. Println ("Area of R2 is:", R2.area ())
    FMT. Println ("Area of C1 is:", C1.area ())
    FMT. Println ("Area of C2 is:", C2.area ())
}

Important points to note when using method

1. Although method is the same name, if the receiver is different, then method is different
2.method can access the recipient's field
3. Call method passes. Access, just like the struct inside the access field

This is illustrated below:

Fig. 2.9 Different method of different struct

In the above example, method area () belongs to Rectangle and Circle, so their Receiver becomes Rectangle and Circle, or the area () is emitted by rectangle/circle.

It is worth noting that the diagram method is marked with a dotted line, meaning that the receiver of the methods here are passed by value rather than by reference, yes, receiver can also be pointers, the difference being that the pointer acts as receiver on the contents of the instance object. The common type as receiver is only a copy of the Action object, does not operate on the original instance object. This will be discussed in detail in the following article.

Is that a method that only works on struct? Of course not, he can be defined in any of your custom types, built-in types, struct and other types above. Are you a little confused here, what is called a custom type, a custom type is not a struct. Oh, struct is just a special type inside a custom type, and other custom type declarations can be implemented with the following declarations.

Copy Code code as follows:

Type TypeName typeliteral

Take a look at the following statement of the custom type of code

Copy Code code as follows:

Type ages int

Type Money float32

Type months Map[string]int

M: = months {
"January": 31,
"February": 28,
...
"December": 31,
}

Did you see it? It's simple, so you can define a meaningful type in your own code, which is actually just an alias, a bit like a typedef in C, such as a ages instead of an int.

Okay, let's get back to method.

You can define any number of method in any custom type, and then let's look at a more complicated example

Copy Code code as follows:

Package Main
Import "FMT"

Const
White = Iota
Black
BLUE
RED
Yellow
)

Type Color byte

Type Box struct {
width, height, depth float64
Color color
}

Type boxlist []box//a slice of boxes

Func (b Box) Volume () float64 {
return b.width * b.height * b.depth
}

Func (b *box) SetColor (c Color) {
B.color = C
}

Func (BL boxlist) Biggestcolor () Color {
V: = 0.00
K: = Color (white)
For _, B: = range BL {
If BV: = B.volume (); BV > V {
v = BV
K = B.color
}
}
Return K
}

Func (BL boxlist) Paintitblack () {
For I, _: = Range BL {
Bl[i]. SetColor (Black)
}
}

Func (c Color) string () string {
Strings: = []string {"White", "Black", "BLUE", "RED", "Yellow"}
return Strings[c]
}

Func Main () {
Boxes: = boxlist {
Box{4, 4, 4, RED},
BOX{10, 1, yellow},
Box{1, 1, black},
BOX{10, 1, BLUE},
BOX{10, 1, white},
BOX{20, Yellow},
}

Fmt. Printf ("We have%d boxes in our set\n", Len (boxes))
Fmt. Println ("The volume of the" The "the", Boxes[0]. Volume (), "cm ³")
Fmt. PRINTLN ("The color of the last one is", Boxes[len (boxes) -1].color. String ())
Fmt. Println ("The biggest one is", boxes.) Biggestcolor (). String ())

Fmt. PRINTLN ("Let's paint them All Black")
Boxes. Paintitblack ()
Fmt. PRINTLN ("The color of the second one is", Boxes[1].color.) String ())

Fmt. Println ("Obviously, now, the biggest one", boxes. Biggestcolor (). String ())
}

The code above defines some constants by using const, and then defines some of the custom types

1.Color as an alias for Byte
2. Defines a struct:box that contains three long and high fields and one color attribute
3. Defines a slice:boxlist that contains box

Some method is then defined for the recipient by the custom type above:

1.Volume () defines the receiver as box, returns the box's capacity
2.SetColor (c color), change the color of box to C
3.BiggestColor () set on top of Boxlist to return the largest color in the list
4.PaintItBlack () Turn all the box colors in Boxlist into black
5.String () defined in color, returns the color of the specific colors (string format)

Is it easy to describe the code above by text? We usually solve the problem through the description of the problem, to write the corresponding code implementation.

Pointers as Receiver

Now let's look back at SetColor this method, its receiver is a pointer to Box, yes, you can use *box. Think about why you use pointers rather than box itself?

The real purpose of our definition of setcolor is to change the color of this box, if you don't pass the box pointer, then SetColor accepts a copy of box, which means that the modification of the color value in method actually only works in box copy, Rather than the real box. So we need to pass in the pointer.

Here you can see receiver as the first parameter of method, and then combine the values and references from the previous function to understand

Here you may ask the SetColor function to define *B.COLOR=C instead of B. Color=c, because we need to read the corresponding values to the pointer.

You are right, in fact go in both ways are correct, when you use the pointer to access the corresponding field (although the pointer does not have any field), go know you have to get the value through the pointer, see, go design is more and more attracted you.

Perhaps attentive readers will ask such questions, paintitblack inside call SetColor should be written (&bl[i). SetColor (black), because the receiver of SetColor is *box, not Box.

You're right, either way, because go knows receiver is a pointer, and he automatically turns you in.

Other words:

If the receiver of a method is *t, you can invoke this method on the instance variable V of a T type without requiring &v to call this method

Similar to

If the receiver of a method is T, you can call this method on a *t type of variable p without requiring *p to call this method

So, you don't have to worry about whether you're calling the pointer's method or not the Method,go know what you want to do, this for many years of C + + programming experience, really solve a great pain.

Method inheritance

We learned the inheritance of the field in the previous chapter, and you will find a magic place for go, and method can be inherited as well. If an anonymous field implements a method, the struct that contains the anonymous field can also call it. Let's look at the following example:

Copy Code code as follows:

Package Main
Import "FMT"

Type Human struct {
Name string
Age int
Phone string
}

Type Student struct {
Human//anonymous fields
School string
}

Type Employee struct {
Human//anonymous fields
Company string
}

A method is defined above the human.
Func (H *human) Sayhi () {
Fmt. Printf ("Hi, I am%s" can call me on%s\n ", H.name, H.phone)
}

Func Main () {
Mark: = student{human{"Mark", "222-222-yyyy"}, "MIT"}
Sam: = employee{human{"Sam", "111-888-xxxx"}, "Golang Inc"}

Mark. Sayhi ()
Sam. Sayhi ()
}

Method overrides

In the example above, what if the employee wants to achieve his sayhi? Simple, as in the case of anonymous field conflicts, we can define a method on employee, overriding the methods of anonymous fields. Take a look at the example below

Copy Code code as follows:

Package Main
Import "FMT"

Type Human struct {
Name string
Age int
Phone string
}

Type Student struct {
Human//anonymous fields
School string
}

Type Employee struct {
Human//anonymous fields
Company string
}

Human definition Method
Func (H *human) Sayhi () {
Fmt. Printf ("Hi, I am%s" can call me on%s\n ", H.name, H.phone)
}

Employee's method overrides the human method
Func (e *employee) Sayhi () {
Fmt. Printf ("Hi, I am%s, I work at%s", called me on%s\n ", E.name,
E.company, E.phone)//yes can split into 2 lines here.
}

Func Main () {
Mark: = student{human{"Mark", "222-222-yyyy"}, "MIT"}
Sam: = employee{human{"Sam", "111-888-xxxx"}, "Golang Inc"}

Mark. Sayhi ()
Sam. Sayhi ()
}


The above code design is so wonderful, so that people unconsciously for go design Marvel!

Through these elements, we can design the basic object-oriented program, but the go inside the object is so simple, there is no private, public keywords, by the case to implement (uppercase at the beginning of the public, lowercase beginning of the private), the same method applies to this principle.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.