Object-oriented in the Go language

Source: Internet
Author: User
Tags error status code posix multiple inheritance in c
This is a creation in Article, where the information may have evolved or changed. [] (https://raw.githubusercontent.com/studygolang/gctt-images/master/object-orientation/gophermessages.jpg) > What is object-oriented? Here I try to share my understanding of how the Go language implements object-oriented, and to make it look more object-oriented than other traditional object-oriented languages. In a previous article, I explored the idea of using functions to express everything, but actually just a safe way to represent a set of functions that always run with the same closures and can run in the same state. It is useful to safely represent a set of functions that run in the same state, but how do you really create abstractions with many different implementations? The object itself does not support this, and each object type has its own set of functions (which we call the set of methods). This is called polymorphism, but when I leave from the traditional object-oriented concept (about objects and types), I find that when designing the software, consider the protocol rather than polymorphism to be more consistent with what should be of interest (detailed later). # # How to define a protocol? First let's define what the protocol is, and for me the Protocol is the set of actions required to achieve the desired result. This concept seems obscure, let me give an example, a more understandable chestnut about an abstract concept, which is I/O. If you want to read a file, the protocol will be: * Open the file * Read the contents of the file * Close the file in order to realize the simple need to read all the contents of a file, you need these three actions, so these actions constitute your "read file" protocol. Now let's take a look at this example and complete the rest of the implementation together. If a function is a first-class citizen in a programming language, there is no difference between structured functions and structured data. We have a method of synthesizing the data, and that is the struct (structs), which we can also use to synthesize functions, for example: "Gotype Reader func (data []byte) (int, error) type Closer func () ErrorType readcloser struct {Read readerclose closer}type Opener func () (*readcloser, error) func usefileprotocol (open Ope NER) {F, _: = Open () Data: = Make ([]byte,] f.read (data) f.close ()}func main () {useFileprotocol (func () (*readcloser, error) {return &readcloser{}, nil})} "is very difficult to express a protocol using a compile-time secure method (if this is not impossible). To illustrate the problem, this example creates a segment error. Another problem is that the code that implements this protocol needs to know that the protocol is implemented to properly initialize the struct (just like the inherited process), or delegate the initialization of the struct to the rest of the system, which will revolve around how to initialize the struct properly. It gets worse when you consider implementing the same functions for multiple protocols. An object that requires some third protocol requires a method: * Articulate the protocol it needs. * Make sure that no functionality is lost when it starts interacting with an implementation. The object that implements the service needs: * To be able to safely represent that it has the necessary functionality to satisfy the protocol. * Able to meet a protocol, even not very clear understanding of it. There is no need for two object interactions to achieve a specific type of common goal, and most importantly, whether the protocols between them match. This is the origin of the Go interfaces (interface). It provides a compile-time secure way to represent the Protocol through the appropriate functions to eliminate all templates of the initialization structure. It will initialize the structure for us and even optimize the initialization structure once, which is called Iface in Go. A vtable similar to C + +. It also allows the code to be decoupled because you do not need to know the package that defines the interface (interface) and implements the interface. Compared to Java and C + + in the same compiled security language, go is more flexible on the basis of go allow. Let's revisit the previous file protocol with interface (interfaces): "Gopackage MainType Reader Interface {Read (data []byte) (int, error)}type Closer interface {Close () Error}type Readcloser interface {Readercloser}type Opener func () (Readcloser, error) type File struct {} Func (f *file) Read (data []byte) (int, error) {return 0, Nil}func (f *file) Close () error {return nil}func usefileprotocol (o Pen Opener) {F, _: = Open () Data: = Make ([]byte,] f.read (data) f.close ()}func main () {Usefileprotocol (func () (Readcloser, error) { Return &file{}, nil})} "a key difference is that this code uses an interface (interface) and is now secure. The ' Usefileprotocol ' does not have to worry about whether the calling function is nil,go the compiler will create a struct that holds a pointer through a ' iface ' descriptor that has all the functionality to satisfy the protocol. It does this by each match of type <-> interface, as it was used (it was initialized for the first time). If you do this, it will still cause a segment error, as follows: "' Gousefileprotocol (func () (Readcloser, error) {var a readcloserreturn A, nil}) ' If it compiles, You can determine that all functions of the calling interface are safe. There is also the interface mechanism of Go, an object can implement many different protocols without knowing these protocols. Is it really useful to implement a protocol? You don't even know it's there. This is useful if you want the code to really be extensible. Let me provide a real case from Nash (Nash: a GitHub open Source Library, Https://github.com/NeowayLabs/nash). # # code extension beyond its original purpose when I tried to write test code for the built-in function exit on Nash, I first learned how powerful Go's interfaces was. The main problem is that it seems that we have to implement different tests for each platform because the exit status code is handled differently on some platforms. I don't remember all the details now, but on Plan9, the exit status is a string type, not an integer type. Basically on one mistake, I want the status code, not just the error, as it was provided on the Cmd.run. (File cmd.run:https://golang.org/pkg/os/exec/#Cmd. Run) has a exiterror type, which I can do: (Exiterror type: https://golang.org/pkg/os/ exec/#ExitError) "GOif Exiterr,OK: = Err. (*exec. EXITERROR); OK {} "at least, this is a bug that was generated by some error states in the course of my execution, but I still can't find the actual status code. So I continued to immerse myself in the Go Source code library to find out how to get the error status code from Exiterror. My clue is processstate, processstate is the internal composition of the EXITERROR structure (Exiterror is the stuct type). Method Sys explains: ' go//Sys returns system-dependent exit information about//the process. Convert it to the appropriate underlying//type, such as Syscall. Waitstatus on Unix, to access its contents.func (P *processstate) Sys () interface{} {return P.sys ()} ' interface{} Nothing can explain , but with its thread, I found a POSIX implementation: ' Gofunc (P *processstate) sys () interface{} {return p.status} ' and p.status what is it, in POSIX: ' ' g Otype waitstatus UInt32 "In an interesting way: ' Gofunc (w waitstatus) exitstatus () int {if!w.exited () {Return-1}return int (w>&gt Shift & 0xFF} "but this is for POSIX, what about other platforms?" Using this advanced detection technology: "' Syscall% grep-r exitstatus. /syscall_nacl.go:func (w waitstatus) exitstatus () int {return 0}./syscall_bsd.go:func (w waitstatus) exitstatus () int {. /syscall_solaris.go:func (w waitstatus) exitstatus () int {./syscall_linux.go:func (w waitstatus) exitstatus () int {./syscall_windows.go:func (w waitstatus) exitstatus () int {return int (W.E Xitcode)}./syscall_plan9.go:func (w waitmsg) exitstatus () int {"" Looks like a public protocol implemented by enough platforms, which is at least sufficient for me (Windows + Linux + plan 9 is enough. )。 Now we have a common agreement on all platforms we can do this: "' go//Exitresult is a common interface implemented by//all Platforms.type Exitresult INTERFAC e {exitstatus () int}if exiterr, OK: = Err. (*exec. EXITERROR); OK {if status, OK: = Exiterr. Sys (). (Exitresult); Ok {got: = status. Exitstatus () if desc.result! = got {t.fatalf ("expected[%d] got[%d]", Desc.result, Got)}} else {t.fatal ("exit result does No t have a Exitstatus method ")}} ' ' Complete code can be found here. (Https://github.com/NeowayLabs/nash/blob/c0cdacd3633ce7a21714c9c6e1ee76bceecd3f6e/internal/sh/builtin/exit_ Test.go) The Sys () method returns an abstract, more precise interface, which would be easier to come up with a new interface, which would be a subset of an interface, and would guarantee compile-time security, rather than checking run-time security. But even if it is a simple way to define a new interface and perform a secure runtime check without changing the source code, the implementation of interface is very concise. In the Java or C + + language, I can't think of a solution that contains the same amount of code/complexity, especially because of the polymorphism-based hierarchy ofBrittle. The check is only allowed in this case if the original code knows the interface you are checking and is obviously inherited from it. In order to solve my problem I have to change the core code of Go, to understand my interface, in Go interfaces, this is not necessary (yay hierarchy). This is important because it allows developers to propose simple objects because they do not have to predict every possible way in which an object might be used in the future, just as it might be useful to have any of the following interfaces. As long as your object's protocol is clear and useful, it can be reused in several ways that you never thought possible. You don't even need to explicitly express the definition and use of an interface. # # What is Object-oriented? This part, I will try to talk about go as a great object-oriented language. All of the early programming languages I came into contact with, like: * java* c++* Python and understanding inheritance, multiple inheritance, diamond inheritance (this is a problem in multiple inheritance in C + +, where two of the parent classes inherit from the same class.) such as The main focus is on the type and inheritance tree, a classification of the exercises. What is a type and an inheritance tree. Just like creating a good classification, will be a good object-oriented design. Further I began to discuss object-oriented with those who say object-oriented is not about this (although all the mainstream object-oriented languages), this design is not flexible. I did not understand, but aroused my curiosity. The best chance to understand it is closest to its core, so I went to find out about Alan Kay's object-oriented material. (Alan Kay Genius Computer Master Arencai, he is one of the inventors of the Smalltalk object-oriented programming environment language, and is also one of the founders of object-oriented programming ideas. There's something more scary to learn from him, but he has an object-oriented keynote speech in OOPSLA (the topic is the computer revolution has not happened yet. Address: Https://www.youtube.com/watch?v=oKg1hTOQXoY), he discussed a bit about object-oriented origins (among other things). He said that object-oriented should focus on what the object is, not the object itself. He even said that the name for more processes would be better, because the object of concern seems to have generated a type of concern and a classification, rather than something that actually exists between this object, which for me is an agreement. The important part of thinking objects is encapsulation (not type). He gives a good example of the cells that they have a clear cell membrane that they allow to go out and also allow to enter. Each of the cells interacting with each other knows nothing about the internal workings of each other, and they don't need to know the other cell types, they just need to implement the same protocol,Trade the same protein etc (I'm not good at biology =)). The focus is on chemical reactions (processes) rather than cell types. So our final encapsulation and explicit protocol as object-oriented should be what, how to develop systems and a great metaphor to mimic biological mechanisms, but because the organic life scale is better than the order of magnitude. Another great metaphor can be extracted from the future of programming demonstrations. When it comes to the beginning of ARPANET and the "Interstellar Computer Network" (Intergalactic computer network), one of the metaphors used to express how the system really expands is how the software integrates with other completely unfamiliar software (even from other planets). Metaphor is great because it shows that good protocols and forms need to do content/agreement negotiation, which is what happens naturally, and perhaps someday what will happen if we meet alien life (hopefully we don't fight foolishly to death). This metaphor even provides some points for dynamic language, but honestly, I don't understand this point, it's good enough to present something (I find it hard to think about something really adapts to no dynamics, even in Go, you need some glue to integrate the object's code by manually creating the protocol). Now the most important point of this metaphor is not to represent the system, but to have the right mindset to look for possible answers, quoting from the speech: "The most dangerous thought so can have an as a creative person I s tothink that you know "what is doing" although I try to keep an open mind, when I think of programming using the metaphor above, I can't find the space to inherit. Alien life will never fuse, because they need a common ancestor that may not exist at all. # # Conclusion The example above I gave has shown a look at how to do more in go, without changing the concept of any preexisting code using the Protocol (GO interfaces) instead of the class. It seems easier to develop according to the opening and closing principle (open closed principle,https://en.wikipedia.org/wiki/open/closed_principle) because I can easily extend other code to do things , it was not originally intended to be without changing it. Both Go and Java have interfaces concepts, which are seemingly misleading because their only common denominator is their name. The creation of an interface in Java is a relationship, not in Go. It simply defines a protocol that can be used to directly integrate objects that do not know each other (they don't even need to know the explicit interface). This seems to be more geared towardsLike, than anything I know so far (of course, I don't know too much =)). # # ACKNOWLEDGEMENTS Special Thanks: * I4K (https://github.com/tiago4orion) * Kamilash (Https://github.com/kamilash) take time to review and point out a lot of stupid mistakes.

via:https://katcipis.github.io/blog/object-orientation-go/

Author: TIAGO Katcipis Translator: Mengyp proofreading: polaris1119

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

402 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.