Go Example Tour (middle)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Introduce

This is from go by example example, spent a few days to write these examples, feel very helpful to me, for beginners, my advice is to look at this go to the book from beginning to end, and then look at these examples, each of the examples are hand-knocking, for your help is still very big. In the process of knocking these examples, there are some questions, there are some knowledge of the expansion, so summed up this article.

Interface Artifact

What is an interface?, plainly, is the collection of a bunch of methods. C + + has no interface, but can be implemented through a pure virtual function interface, in Java is born with the concept of interface, but I want to say that Golang interface is stronger than both. Whether C + + or Java for a specific class need to implement the corresponding interface of all methods to be abstracted by this interface, and Golang do not need, golang you only need to implement the interface of at least one method. For example, the classic penguin is a bird but does not fly the problem, C + + and Java have no way to let penguins achieve a bird interface, but Golang can simplify this design, only need to realize the bird interface in addition to fly this method of other methods. There is also an empty interface in Golang interface{} , which can represent any type, and this function can receive any type of data if the null interface is used as a function parameter. But the empty interface has a very ugly design, see this code:

func PrintAll(vals []interface{}) {    forrange vals {        fmt.Println(val)    }}func main() {    names := []string{"test1","test2","test3"}    PrintAll(names)}

According to the above description, the null interface should be able to accept any type of data, the above code can theoretically run normally, but I do not say I lied, the direct compilation run will have the following error:

cannot use names (type []stringtype []interface{}into PrintAll

The two can't actually do the conversion directly, not to say that the empty interface can receive any type of data? Yes, but the code above needs to be changed.

func PrintAll(vals []interface{}) {    forrange vals {        fmt.Println(val)    }}func main() {    names := []string{"test1","test2","test3"}    make([]interface{},len(names))    forrange names {        vals[i] = v    }    PrintAll(vals)}

Now can work properly, biased to the first assignment to an empty interface. This design has some ugly. Another good thing about the Golang interface is that you can design a method to receive pointers that can also be designed to receive value, which is OK. However, there are still some misunderstandings, please see the following code:

type  Animal interface  {Speak () string } type  Dog struct  {}func  (d Dog) Speak () string  {return  " Woof "}< Span class= "Hljs-keyword" >type  Cat struct  {} Func  (c Cat) Speak () string  {return  Span class= "hljs-string" > "Meow" }func  Main () {animals: = []animal{dog{},cat {}} for  _,animal: = range  animals {fmt. PRINTLN (animal. Speak ())}}  

The above code declares the animal interface, and then the dog and cat implement this interface. Then the dog and cat are abstracted by the animal interface in the main function, and the corresponding speak method is called in turn. The code above works fine until one day I change the cat's Speak method from the original to (c Cat) (c *Cat) receive a pointer. Run the above code again and an error has occurred:

cannot use Cat literal (typeastypeinarray element:    notmethod has pointer receiver)

A value is passed in Cat{} , and the Speak method of cat is to receive a pointer. OK, change the code to Cat{} change new(Cat) , now it works, now try to (c *Cat) change back (c Cat) and then still pass a cat pointer to this method. You're going to find out. The final conclusion is that the value type cannot be passed to the method that receives the pointer, but the pointer type can be passed to the method that receives the value. is not feeling a bit ugly in design. But this is all for a reason, more content can be referred to the following two articles:

    • How to use interfaces in Go
    • Go Data structures:interfaces

Proprietary error-handling methods

In Golang error handling is done by the return value, Golang built-in an error interface, in general you can directly through the errors.New production of an error message with the specified value, if you want to design an error type for your type, You only need to customize an error type, then implement Error the interface, the code is as follows:

 PackageMainImport "Errors"Import "FMT"//Returns an error, via errors. New creates an Error objectfuncF1 (ARGint) (int, error) {ifarg = = the{return-1, errors. New ("Can ' t work with")    }returnArg +3,Nil}typeArgerrorstruct{argintProbstring}//Defines an error for the structfunc(e *argerror) Error ()string{returnFmt. Sprintf ("%d-%s", E.arg,e.prob)}//As long as the error method is implemented, it can be accepted by error, and error is an interfacefuncF2 (ARGint) (int, error) {ifarg = = the{return-1, &argerror{arg,"can ' t work with it"}    }returnArg +3,Nil}funcMain () {//Traverse Slice, call F1 and F2 for each value method     for_,i: =Range[]int{7, the} {ifR,e: = F1 (i); E! =Nil{FMT. Println ("F1 failed:", e)}Else{FMT. Println ("F1 worked:", r)}} for_,i: =Range[]int{7, the} {ifR,e: = F2 (i); e!=Nil{FMT. Println ("F2 failed:", e)}Else{FMT. Println ("F2 workded:", r)}}}

In addition to the ability to customize the error type, you can also extend the error interface, for more information about error can be found in the following article:

Error Handling and Go

CSP model and Channel

Golang in the goroutine is a typical CSP model, each process is a work, each work through the new channel communication, channel is like a channel, similar to the Unix pipe, and actor model very similar. Channel Golang in the default is no buffer, that is, only one message can be sent at a time, and only wait for the other party to receive the message before the sending again, if there is no message in the channel will cause blocking, know that there is a message.

done := make(chan bool,1)   //创建了一个bool类型的channel,buffer大小是1donetrue                //向channl发送消息flag := <-done              //从chanlle中接收消息

The channel is full-duplex by default, but you can set the channel to only send or receive.

pings <-chanstring         //只能发的channelchanstring         //只能收的channel

In addition, the channel can be closed, when the channel is closed, there is no message to send, at this time if you read the channel will immediately return to non-empty error,channel can also use for range to traverse, The precondition is to close the channel, otherwise it will block when traversing.

Select IO Multi-channel take

Write network programming know that IO multi-take, that is, the same time can listen to multiple sockets, Golang at the language level provides the SELECT keyword, but this is not used to listen to sockets, but to monitor multiple channel simultaneously. Here is an example of a select use:

 PackageMainImport "Time"Import "FMT"funcMain () {c1: = Make(Chan string) C2: = Make(Chan string) FMT. Println (time. Second)//Two co-processes via C1 and C2 communication    Go func() {time. Sleep (time. Second *1) C1 <-"One"}()Go func() {time. Sleep (time. Second *2) C2 <-"both"}()//select monitoring multiple descriptors     forI: =0; I <2; i++ {Select{ CaseMSG1: = <-c1:fmt. Println ("Received", MSG1) CaseMSG2: = <-c2:fmt. Println ("Received", MSG2)}}}

The default channel read and write is blocked, can be made non-blocking by combining select, by adding default in Select, when all of the above channel has no message, will immediately jump to default. This makes it possible to implement non-blocking skillfully.

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.