Go Series Tutorial--17. Method

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed. Welcome to the 17th Tutorial [Golang Series Tutorial] (/SUBJECT/2). # # # What is a method? The method is actually a function that adds a special receiver type to the middle of the keyword and method name ' Func '. A sink can be a struct type or a non-struct type. The receiver is accessible inside the method. Here is the syntax for creating a method. The code snippet above "Gofunc (t type) methodName (parameter list) {}" creates a method ' MethodName ' with a receiver type of ' types '. The # # # Method Example lets us write a simple applet that creates a method on the struct type and invokes it. "' Gopackage mainimport (" FMT ") type Employee struct {name string salary int currency string}/* displaysalary () method will Emplo Yee as receiver type */func (e Employee) displaysalary () {fmt. Printf ("Salary of%s is%s%d", E.name, E.currency, E.salary)}func main () {emp1: = Employee {name: "Sam Adolf", Salary:5 Currency: "$",} emp1.displaysalary ()//Call the Displaysalary () method of the Employee type} "[Run Program Online] (https://play.golang.org/p/ Rrsi_swaoz) in line 16th of the above program, we created a ' displaysalary ' method on the ' Employee ' struct type. The Displaysalary () method accesses the receiver ' e Employee ' inside the method. In line 17th, we use the receiver ' e ' and print the 3 fields of the employee's name, currency, and salary. In line 26th, we call the method ' Emp1.displaysalary () '. Program output: ' Salary of Sam Adolf is $5000 '. # # # Why do we have a function and we need a method?? The above program has been rewritten to use only functions, no method. "' Gopackage mainimport (" FMT ") type Employee struct {name string salary int currency String}/*displaysalary () method is converted to a function, The Employee is passed as a parameter. */func displaysalary (e Employee) {fmt. Printf ("Salary of%s is%s%d", E.name, E.currency, E.salary)}func main () {emp1: = employee{Name: "Sam Adolf", salary:50 XX, Currency: "$",} displaysalary (EMP1)} "[Running Program Online] (https://play.golang.org/p/dFwObgCUU0) in the above program, ' Displaysalary ' The method is converted to a function, and the ' Employee ' struct is passed as a parameter to it. This program also produces exactly the same output: ' Salary of Sam Adolf is $5000 '. Now that we can write the same program using functions, why do we need a method? There are several reasons why we have to look at each other. -[Go is not a purely object-oriented programming language] (https://golang.org/doc/faq#Is_Go_an_object-oriented_language), and go does not support classes. Therefore, a type-based approach is a way to implement and class similar behavior. -the same name method can be defined on different types, and the function of the same name is not allowed. Suppose we have a ' Square ' and ' Circle ' structure. You can define an ' area ' method on ' Square ' and ' Circle ' separately. See the procedure below. "' Gopackage mainimport (" FMT "" math ") type Rectangle struct {length int width int}type Circle struct {radius float64}fu NC (R Rectangle) area () int {return r.length * R.width}func (c Circle) isA () float64 {return math. Pi * C.radius * c.radius}func Main () {r: = rectangle{length:10, Width:5,} fmt. Printf ("Area of Rectangle%d\n", R.area ()) c: = circle{radius:12,} fmt. Printf ("Area of Circle%f", C.area ())} "[Running Program Online] (Https://play.golang.org/p/0hDM3E3LiP) The program output: ' Area of rectangle The properties of the method above 50Area of Circle 452.389342 "are used in the interface. We'll discuss this in the next tutorial. # # # pointer receiver and value receiver so far, we've only seen methods that use value sinks. You can also create methods that use the pointer sink. The difference between a value receiver and a pointer sink is that changes within the method of the pointer sink are visible to the caller, but the value sink is not the case. Let's use the following procedure to help understand this. ' Gopackage mainimport ("FMT") type Employee struct {name string age int}/* method that uses a value sink. */func (e Employee) changename (NewName string) {E.name = newname}/* method using the pointer sink. */func (e *employee) changeage (newage int) {e.age = Newage}func main () {e: = employee{name: "Mark Andrew", age:50,} f Mt. Printf ("Employee name before change:%s", e.name) e.changename ("Michael Andrew") fmt. Printf ("\nemployee name after change:%s", e.name) fmt. Printf ("\n\nemployee Age before Change:%d", e.age) (&e). Changeage (Wuyi) fmt. PriNTF ("\nemployee Age following change:%d", E.age)} "[Running Program Online] (Https://play.golang.org/p/tTO100HmUX) in the program above, ' ChangeName ' The method has a value receiver ' (e Employee) ', and the ' Changeage ' method has a pointer receiver ' (e *employee) '. Changes made to the field ' name ' of the ' Employee ' struct in the ' changename ' method are not visible to the caller, so the program prints the same name before and after invoking ' E.changename ' ("Michael Andrew") method. Because the ' changeage ' method is using the pointer ' (e *employee) ' receiver, the call ' (&e) ' will be visible to the caller when the change to the ' age ' field is made by the Changeage (51) ' method. The program output is as follows: "' Employee name before Change:mark andrewemployee name after Change:mark Andrewemployee age before Change:50em Ployee age after change:51 ' in line 36th of the above program, we use ' (&e). Changeage (51) ' to invoke ' Changeage ' method. Because the ' changeage ' method has a pointer sink, we use ' (&e) ' to invoke this method. In fact, without this need, the go language allows us to directly use ' E.changeage (51) '. ' E.changeage (51) ' will automatically be interpreted by the go language as ' (&e). Changeage (51) '. The following [program] (HTTPS://PLAY.GOLANG.ORG/P/NNXBSR3UC8) overrides, using ' E.changeage (51) ' instead of ' (&e). Changeage (51) ', which outputs the same result. ' Gopackage mainimport ("FMT") type Employee struct {name string age int}/* method that uses a value sink. */func (e Employee) changename (NewName string) {e.name = newname}/* method that uses the pointer sink. */func (e *employee) changeage (newage int) {e.age = Newage}func main () {e: = employee{name: "Mark Andrew", age:50,} f Mt. Printf ("Employee name before change:%s", e.name) e.changename ("Michael Andrew") fmt. Printf ("\nemployee name after change:%s", e.name) fmt. Printf ("\n\nemployee Before Change:%d", e.age) e.changeage (Wuyi) fmt. Printf ("\nemployee Age after Change:%d", E.age)} "[Running Program Online] (HTTPS://PLAY.GOLANG.ORG/P/NNXBSR3UC8) # # # So when to use the pointer receiver, When do I use a value receiver? In general, a pointer sink can be used when: changes made to sinks inside a method should be visible to the caller. The pointer receiver can also be used in the following scenario: When copying a struct is too expensive. Consider that the next struct has a lot of fields. It is expensive to use this struct as a value receiver to copy the entire structure within a method. In this case, the pointer sink is used, the struct is not copied, and only a pointer is passed to the method for internal use. In all other cases, the value receiver can be used. # # # Anonymous fields methods that are part of the struct's anonymous field can be called directly, as if these methods were part of the struct that defines the anonymous field. ' Gopackage mainimport ("FMT") type address struct {City string state String}func (a address) fulladdress () {fmt. PRINTF ("Full address:%s,%s", A.city, a.state)}type person struct {firstName string LastName string Address}func main () {p: = person{FirstnamE: "Elon", LastName: "Musk", address:address {city: "Los Angeles", State: "California",},} p.fulladdress ()//Access Addres s struct fulladdress method} ' [Online Run Program] (HTTPS://PLAY.GOLANG.ORG/P/VURNIMW4_9) on line 32nd of the above program, we access ' by using ' p.fulladdress () ' The ' fulladdress () ' method of the address ' struct '. The explicit invocation of ' p.address.fulladdress () ' is not necessary. The program output: ' Full Address:los Angeles, California ' # # # # # # # # # # # # # # # # # # # # # # # # # # # # I'll try to be clear about it. When a function has a value parameter, it can only accept one value parameter. When a method has a value sink, it can accept a value sink and a pointer sink. Let's take an example to understand this. ' Gopackage mainimport ("FMT") type rectangle struct {length int width int}func area (r rectangle) {FMT. Printf ("area Function Result:%d\n", (R.length * r.width))}func (R-Rectangle) area () {FMT. Printf ("area Method Result:%d\n", (R.length * r.width))}func main () {r: = rectangle{length:10, Width:5,} area (R) R.A Rea () P: = &R/* Compilation error, cannot use P (type *rectangle) as type rectangle on argument to area *///area (P) P.area ()//Call value receiver by pointer} "' [Online Run Program] (Https://play.golang.org/p/gLyHMd2iie) line 12th of function ' F 'The UNC area (r rectangle) ' accepts a value parameter, and the method ' func (r rectangle) area () ' accepts a value sink. In line 25th, we call the area function by the value parameter ' area (r) ', which is legal. Again, we use the value receiver to invoke the area method ' R.area () ', which is also legal. In line 28th, we create a pointer to ' R ' for ' P '. If we try to pass this pointer to a function area that can accept only one value parameter, the compiler will give an error. So I commented on line 33rd of the code. If you remove the code comment from this line, the compiler will throw an error ' compilation error, cannot use P (type *rectangle) as type rectangle in argument to area. This will throw an error as expected. Now to the tricky part, the code in line 35th ' P.area () ' uses the pointer receiver ' P ' to invoke the method ' area ' that accepts only one value receiver. This is completely effective. The reason is that when ' area ' has a value receiver, it is convenient for the go language to interpret ' P.area () ' as ' (*p). Area () '. The program will output: ' Area function Result:50area method Result:50area method Result:50 ' # # # # # # # # # # # # # # # # # # # in methods using a pointer receiver is similar to using a pointer parameter and a value parameter in a function, a function uses Pointer parameters only accept pointers, and methods that use the pointer sink can use value sinks and pointer sinks. ' Gopackage mainimport ("FMT") type rectangle struct {length int width int}func perimeter (r *rectangle) {FMT. PRINTLN ("Perimeter function Output:", (R.length+r.width))}func (R *rectangle) perimeter () {FMT. Println ("Perimeter method Output:", "R.length+r.width")}func Main () {r: = rectangle{length:10, Width:5,} p: = & R//pOinter to R perimeter (p) p.perimeter ()/* Cannot use R (type rectangle) as type *rectangle on argument to perimeter *///p Erimeter (R) r.perimeter ()//Use a value to invoke the pointer receiver} ' [Online Run Program] (Https://play.golang.org/p/Xy5wW9YZMJ) on line 12th of the above program, Defines a function ' perimeter ' that accepts pointer parameters. Line 17th defines a method that has a pointer sink. In line 27th, we passed a pointer parameter when we called the perimeter function. In line 28th, we call the perimeter method through the pointer sink. Everything looks So perfect. In the 33rd line that is commented out, we try to call the function ' perimeter ' by passing in the value parameter ' r '. This is not allowed because the pointer parameter of the function does not accept the value parameter. If you remove the code comment from this line and run the program, the compiler will throw an error ' Main.go:33:cannot use R (type rectangle) as type *rectangle in argument to perimeter. In line 35th, we call the method ' perimeter ' with the pointer receiver by the value receiver ' r '. This is permitted, in order to facilitate the go language to interpret the Code ' R.perimeter () ' as ' (&r). Perimeter () '. The program outputs: "' Perimeter function Output:30perimeter method output:30perimeter methods Output:30 ' ' # # # # on the non-structural approach so far, We define the method only on the struct type. You can also define a method on a non-struct type, but there is a problem. * * In order to define a method on a type, the receiver type definition of the method and the definition of the method should be in the same package. So far, all the structures and structures we have defined are in the same ' main ' package, so they can be run. * * ' Gopackage mainfunc (a int) add (b int) {}func main () {} "[Run Program Online] (https://play.golang.org/p/yBxlf5o_la) in line 3rd of the above program, we try to add an ' add ' method to the built-in type ' int '. This is not allowed because the definition of the ' add ' method is not in the same package as the definition of the ' int ' type. The program throws a compilation error ' cannot define new methods on non-local type int '. The way that the program works is to create a type alias for the built-in type int, and then create a method that aliases the type as a sink. "' Gopackage mainimport" FMT "type MyInt intfunc (a myInt) Add (b myInt) MyInt {return a + B}func main () {num1: = myInt (5) Num2: = myInt (Ten) Sum: = Num1.add (num2) fmt. Println ("Sum is", sum)} "[Running Program Online] (Https://play.golang.org/p/sTe7i1qAng) on line 5th of the above program, we created a type alias ' myInt ' for ' int '. In line 7th, we define a method ' add ' that takes ' myInt ' as the receiver. The program will print out ' Sum is 15 '. I have created a program that contains all the concepts we have discussed so far, as described in [GitHub] (https://github.com/golangbot/methods). This is the approach in go. I wish you a wonderful day. * * Previous tutorial-[structure] (https://studygolang.com/articles/12263) * * * * Next tutorial-[interface-I] (https://studygolang.com/articles/12266) * *

via:https://golangbot.com/methods/

Author: Nick Coghlan Translator: MDGSF proofreading: Rxcai

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

2,773 Reads
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.