1024programmer Java Why does Go language put type declarations at the end?

Why does Go language put type declarations at the end?

Regarding types, there is a section on the official website that carefully introduces function pointers. The current design is much clearer than C syntax.

In other words, the type is placed behind to make it clearer and easier to understand. Rob Pike once explained this problem on the official Go blog (see the original text: Go’s Declaration Syntax). The brief translation is as follows (Sorry for the inaccuracies in the translation due to limited translation skills):

Introduction

Newcomers to the Go language often wonder why the declaration syntax of this language is different from the traditional C family language. In this blog post, we will make a comparison and answer it.

C syntax

First, let’s take a look at C’s syntax. C uses a clever and unusual declaration syntax. When declaring a variable, just write an expression with the name of the target variable, and then specify the type of the expression itself in the expression. For example:

 int x;

The above code declares the x variable and its type is int – that is, the expression x is of type int. Generally speaking, in order to specify the type of a new variable, we have to write an expression that contains the variable we want to declare. The result value of this expression operation belongs to some basic type. We write this basic type into the expression to the left. Therefore, the following statement:

 int *p;
 int a[3];

specifies that p is a pointer of type int, because *p is of type int. And a is an int array, because the type of a[3] is int (ignore the index value that appears here, it is just used to indicate the length of the array).

Let’s look at the function declaration next. In the C function declaration, the parameter types are written outside the parentheses, like the following:

 int main(argc, argv)
   int argc;
   char *argv[];
 { /* ... */ }

As mentioned earlier, we can see that main is a function because the expression main(argc, argv) returns an int. In modern notation we write it like this:

 int main(int argc, char *argv[]) { /* ... */ }

Although they look a little different, the basic structure is the same.

Overall, C’s syntax is very smart when the types are relatively simple. But unfortunately, once the types start to become complicated, C’s syntax can quickly become confusing. Famous examples are function pointers, which we have to write as follows:

 int (*fp)(int a, int b);

Here, fp is a pointer because if you write an expression like (*fp)(a, b) it will call a function that returns a value of type int. What happens if one of the parameters of fp is itself a function?

 int (*fp)(int (*ff)(int x, int y), int b)

This is a bit difficult to read.

Of course, we do not need to specify the names of parameters when declaring a function, so the main function can be declared as:

 int main(int, char *[])

Recall that argv was as follows

 char *argv[]

Have you ever noticed that you are constructing the variable type by removing the variable name from the “middle” of the declaration? Although it may not be obvious, when you declare a variable of type char *[], you actually need to insert the name into the middle of the variable type.

Let’s see what happens if we don’t name the parameters of fp:

 int (*fp)(int (*)(int, int), int)

The difficult part about this thing is not just remembering that the parameter name was originally placed in the middle

 int (*)(int, int)

What makes it even more confusing is that it may not even be clear that this is a function pointer declaration. Let’s take a look at what happens if the return value is also a function pointer type

 int (*(*fp)(int (*)(int, int), int))(int, int)

This is hardly a statement about fp.

You can construct more complex examples yourself than this, but this should suffice to explain some of the complexities introduced by C’s declaration syntax.

One more thing needs to be pointed out. Since the type syntax and declaration syntax are the same, it may be difficult to parse expressions with types in the middle. This is why C always encloses the type in parentheses when doing type conversion, like this

 (int)M_PI

Go’s syntax

Languages ​​outside the C family usually use a different type syntax when declaring. The name usually comes first, often followed by a colon. Written in this way, the example we gave above will become as follows:

 x: int
 p: pointer to int
 a: array[3] of int

Such a statement, if somewhat verbose, is at least clear – you just have to read it from left to right. The solution adopted by the Go language is based on this, but in order to pursue simplicity, the Go language lost the colon and removed some keywords, which became the following:

 x int
 p*int
 a [3]int

in [3]intThere is no direct correspondence with the use of a in expressions (we will come back to the issue of pointers in the next section). At this point, you get an improvement in code clarity, but the price you pay is that syntax needs to be treated differently.

Now let’s consider the issue of functions. Although in the Go language, the main function actually has no parameters, let’s first copy the previous declaration of the main function:

 func main(argc int, argv *[]byte) int

At first glance it is no different from C, but it looks good when read from left to right.

The main function accepts an int and a pointer and returns an int.

If you remove the parameter name at this point, it is still clear – because the parameter name always comes before the type, there will be no confusion.

 func main(int, *[]byte) int

One value of this left-to-right style of declaration is that as types become more complex, they remain relatively simple. The following is the declaration of a function variable (equivalent to a function pointer in C language)

 f func(func(int,int) int, int) int

Or when it returns a function:

 f func(func(int,int) int, int) func(int, int) int

The above declaration is still very clear to read, from left to right, and it is easy to understand which variable name is currently declared – because the variable name always comes first.

The difference between type syntax and expression syntax makes it easier to call closures in Go language:

 sum := func(a, b int) int { return a+b } (3, 4)

Pointer

There are some exceptions to pointers. Note that in arrays and slices, Go’s type syntax places the square brackets on the left side of the type, but in the expression syntax, the square brackets are placed on the right side:

 var a[]int
 x = a[1]

Similarly, Go’s pointers follow C’s * notation, but when we write, we declare * to the right of the variable name, but in expressions we have to put * to the left:

 var p*int
 x = *p

Cannot be written as follows

 var p*int
 x = p*

Since the suffix * can be confused with multiplication, maybe we could use Pascal’s ^ notation instead, like this

 var p^int
 x = p^

We probably really should change * to ^ as above (of course the symbol of the xor operation must also be changed), because the * prefix in types and expressions does make many things a bit confusing. Complex, for example, although we can write like this

 []int("hi")

But when converting, if the type starts with *, you have to add parentheses:

 (*int)(nil)

If one day we are willing to give up using * as pointer syntax, then the above brackets can be omitted.

It can be seen that Go’s pointer syntax is similar to C. But this similarity also means that we cannot completely avoid the situation where parentheses are sometimes needed in grammars to avoid ambiguity between types and expressions.

In summary, despite its shortcomings, we believe that Go’s type syntax is easier to understand than C’s. Especially when the type is complex.

Summary

The above is the entire content of this article. I hope that the content of this article has certain reference and learning value for everyone’s study or work. Thank you for your support. If you want to know more related content, please check out the relevant links below

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/784270

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索