Translation Go programming language, or: Why in addition to it, the other Class C language is garbage (3)

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

Continue with the translation of the previous article. The Go is introduced further. A German, written in English such a lengthy speech, this is what kind of internationalism spirit ...

——————— – Translate split line ——————— –

Go programming language, or: Why besides it, other C language is garbage

Translation Go programming language, or: Why in addition to it, the other Class C language is garbage (1)

Translation Go programming language, or: Why in addition to it, the other Class C language is garbage (2)

Extended

Go really powerful is that until now, those who cannot find the corresponding place in C, C + + or any other language mentioned above. These are the ones that really make Go shine:

Type-based object vs. encapsulation

No class. methods on types and types are not dependent on each other. You can define a method on any type, or you can define any type as a new type, similar to a typedef in C. Unlike C or C + +, where a new named type has its own collection of methods, the main types (those that are the basis) also have a collection of methods:

Type Handle Int64func (this Handle) string () string {    return ' This is a Handle object ' cannot be represented as St Ring. "} var global Handle

In this example, Global. String () can be called. Further, we obtain an object system that has no virtual method. It's not any trouble at runtime, it's just a grammar candy.

Duck type (refer to Wikipedia) vs. polymorphism

A type definition cannot make two independent types look similar. Independent types are independent types, and it is not allowed to create a generic type to implement polymorphism in a strictly typed language. A popular example in most languages is the rule that value transforms the string that expresses it. The Handle type defines such a method with Go rules, but does not show how to make any type have such a String method.

C + + uses interfaces (which may take advantage of virtual base classes) and overloads operators to implement this. Java's toString is part of the root class and is therefore inherited, and other invocation rules are expressed according to the interface.

Go uses the interface somewhat special. Unlike Java, it does not need to define a given type to match an interface. If it works, it automatically acts as that interface:

Type Stringer Interface {    string () string}

That's all that's needed. Automatically, the Handle object can now be used as a Stringer object. If it walks like a duck, it barks like a duck and looks like a duck, it is a duck from any practical use. Now the best part: it can work on the fly. There is no need to import and even developers need not know the definition of interfaces.

When the type is used as an interface, the runtime environment constructs a table of function pointers in order to get the ability to reflect the runtime of the interface. This will have some runtime overhead. However this is optimized, so there is only a small loss. Interface tables are calculated only when they are actually used, and only once for each type. If the actual type can be determined at compile time, it is completely avoided at run time. Method scheduling should be slightly faster than Apple's (already pretty cool) Objective C schedule.

Type embedding vs. inheritance

Types work like classes, but they are actually different because there is no hierarchy of inheritance. In the previous example, Handle did not inherit any method from the int64. You can define a type structure to implement something like inheritance by including the underlying data type in the declaration body: (shameless example of stealing from "effective Go")

Type readwriter struct {    *bufio. Reader        *bufio. Writer}

Bufio. Reader and Bufio. Writer has all the methods of this type. The conflict is solved with a very simple rule. After all, this is not multiple inheritance! Each underlying type exists as a separate data object in the Union type, and each method from the subtype can see only the objects it owns. This way, you get good practical behavior, without the hassle of having multiple inheritance of classes. Throw away all the concepts-more or less a syntactic sugar, which makes the code more expressive without the overhead of running.

This also works on interfaces. The Union type matches all of the interfaces that make up the type. The rules for resolving the ambiguity of a quoted method are very simple, and unpredictable situations are simply forbidden. Union types are free to rewrite the composition of the method as needed.

Visible control

The main unit in development is the package. One or more files implement a package, and you can control the visibility of access from outside the package. There is no complex visible system, just visible or invisible. This is controlled by typographic rules: Public names start with uppercase letters, and private names are in lowercase letters. This is valid for all names.

This is a rather pragmatic approach. Unlike the type system, which is quite powerful in the competition, Go occupies Middle-earth: Most scripting languages do not care about visibility at all or rely on conscious regulation, while the school-style C language has access control details. Again, this is a good thing for the Go object model. Because there is no class inheritance and the embedded object is fully associative, there is no need for an Access protection rule. You'll see how this works in practice.

No constructors

The object system has no special constructors. Here is a concept of a value of 0, such as all fields with 0 initialization type. This requires that when writing code, a value of 0 is meaningful for legitimate "empty" object processing. If this is not possible, the constructor is provided as a package function.

Goroutine and Channel

For this universal programming language, this is the most unusual feature. Goroutine can be thought of as a very light-weight thread. The Go runtime maps these to a multi-tasking, or real operating system thread, as PTH, which has a lower overhead, and the latter gets the best of both by threading the non-blocking behavior.

A Channel is a message queue that has a type of cache or no cache. A simple implementation, really. Load objects from one side and remove them from the other side. Many of the things you have to do in parallel algorithms are no longer needed.

Go makes Goroutine a first-class citizen a big step forward, and many algorithms can be used as the core. The stack of the same segment makes the minimum stack usage of each thread relatively low, and the performance advantage is obtained by simulating the thread, unless a blocking system call is used, which is a little more overhead than a normal function call.

To sum up, Go has the real ultimate weapon, goroutine can be used in many places, rather than standard concurrency algorithms. Python's generator function can be used as a model, or as a custom free-object memory management table. This simple concurrency implementation is a magical thing to see online documentation.

By the way, by setting the environment variable, you can tell the Go how many CPUs you want to use, so that Goroutine will map several native threads at the beginning (by default, no other threads are turned on if there are no blocked system calls).

Defects

No system is perfect. Go has some flaws, here's a list of what I'm encountering now:

Binary size/run-time dependent

The basic Go binary is a static link, if the compilation does not include debug information, about 750k. This is the same size as a similar C program. I've tested it with the "compare tree" example on the Go homepage and compared it to my C implementation of a similar structure.

GCCGO can compile dynamically-linked execution files, but libc on all systems, and usually does not need to consider dependencies, while LIBGO has an additional package of approximately 8MB. As a comparison: libstdc++ less than 1 mb,libc less than 2MB. To be fair, they do a lot less work than the standard library of Go. However, there is a big difference and a dependency problem.

6g/8g, the native Go compiler, produces similar execution files, but does not rely on libc, which are truly independent. It is also not possible to implement dynamic connections at run time.

This also involves small systems. Next to me is the old 16MB Pentium-100 notebook, running X and JWM desktop, playing my music collection happily. It even has 5MB of memory for disk buffering. Is it possible to write such a system with Go?

The right to be unfair

This language has privileges in many ways. For example, the work done by the special make () function cannot be extended with the user's code. This is not as bad as it seems at first, such as writing some code that works the same as make (), but there is simply no way to strengthen the language's structure. The same problem exists on other calls and reserved words that may need to be extended, such as range. You are more or less obligated to use Goroutine and channel extensions to extend an advanced out.

I'm not sure this is really a problem. Assuming that the map, slice, goroutine, and channel are optional implementations, the impact of this restriction does not exist. It does not compromise the clarity and readability of the code, but it can be a bit unfair if you use a "can imitate anything" language such as Perl or Python.

No overloads

Overloading is the source of many semantic ambiguities. There's a good reason to let it go. However, simultaneous overloading, especially operator overloading, is so convenient and readable that I miss it very much. Go does not have an automatic type conversion, so things are not as creepy as they are in C + +.

As an example, the overloads may be used where the large number of libraries, (number) vectors, matrices, or finite sample data types are envisaged. When dealing with Kua platform data exchange, it can be a huge victory to modify the mathematical semantics for special data types. For the processing of antique machine data, there can be a supplementary number type, for example, with the operation of fully simulating the target platform, instead of relying on the same semantics of the current platform.

Limited Duck Type

Unfortunately, the type of duck is not complete. Imagine an interface like this:

Type arithmetic interface {    ADD (other int) arithmetic}

The parameters and return values of the function add will limit the automatic typing. An object with the method func (this MYOBJ) ADD (other int) MYOBJ does not match arithmetic. There are many examples like this, and some of them are hard to decide whether they should be covered with duck type, or the current rules are better. You may fall into many less obvious problems, so this is an example of "keeping it simple and probably better", but I always find it inconvenient.

Russ, one of the authors of the Cox,go core, explains:

This does not work because the MYOJB memory layout differs from the arithmetic memory layout. Even other languages that match the memory layout are tangled up in this. Go just said "no".

I guess I need to define the func (this MYOBJ) ADD (other int) arithmetic instead. The benefit of compromised scenarios is that the compiler and the generated machine code are simpler.

Pointer vs. value

I'm not sure I'm happy about this pointer/value thing. All Java is referred to as simpler semantics. The syntax for C + + reference vs. values is also good. One possible aspect is that you gain more control over the memory layout and usage structure, especially when other structures are included, while the value vs. reference semantics are clear at the time of function invocation and C + + is unpredictable.

By the way, map and slice are reference types. At first, I was annoyed with them, but you could construct your own object with similar behavior: The structure containing the (private) pointer, which is more or less what map and slice do. Now only if there is a way to hook up to its [...] grammar ...

Logical context: ternary operator, remember? )

The logical context provides many possibilities for simplifying the code. Unfortunately, although the!pointer is still clear, the pointers still have to be compared to nil. Further, there is no pointer operation from now on. Refer to the above expected tenth article. Keep the code neat and short.

Give each type a 0 value concept, which makes up for the lack of a logical context.
——————— – Translate split line ——————— –
The Germans stromag the review and added a lot of content. The heart is cold, the pit is digging deeper ...

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.