Go language | Go 1.9 New features Type alias detailed

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

This article for the original article, reprint annotated source, welcome to sweep the code to pay attention flysnow_org to the public number or website http://www.flysnow.org/, the first time to see the following wonderful articles. Feel good, and share to friends Circle, thank you for your support.

Beijing Time 2017.08.25,go1.9 official version released. Go1.9 through 2 beta, months, finally, released the official version. Go 1.9 contains a lot of changes, such as type alias, security concurrency map, parallel compilation and so on, is a big change, today this article mainly introduces the type alias.

Install Go 1.9

For many well-known reasons, you may not be able to download the latest Go 1.9 SDK, if you do not have a ladder, can be downloaded to my self-built mirror site, there are a lot of common development software, which contains the latest go 1.9. Mirror address: http://mirrors.flysnow.org/

Role

The primary purpose of this feature is to use a defined type that is compatible with the movement of the package. For example, we have an export type that we are flysnow.org/lib/T1 migrating to another package, for example flysnow.org/lib2/T1 in.

Without the type alias when we do this, it will cause other third parties to reference the old package path code, must be uniform modification, otherwise it will not be used.

With a type alias is not the same, the implementation of type T1 we can migrate to lib2, while we in the original Lib under the definition of a lib2 under the T1 alias, so that the third-party reference can not be modified, or normal use, only to be compatible for a period of time, Completely removing the type compatibility in the old package allows you to refactor our code incrementally instead of fits.

12
//package:flysnow.org/lib type T1=lib2. T1

Type alias vs defintion

We create a new type based on a type, called defintion; Create an alias based on a type called Alias, which is their biggest difference.

12
type int type int

The first line of code is based on the primitive type int that created the new type MyInt1, the second line is the type alias MyInt2 created for an int, note that the type alias is defined = .

1234
var int =0var//errorvar i2 MyInt2 = ifmt. Println (I1,I2)

Looking closely at this example, the second line assigns a variable of type to a int i MyInt1 variable of type that i1 is prompted to compile the error: the type cannot be converted. But the third row int assigns the variable of type to the i MyInt2 variable of type, i2 and does not prompt the error.

As you can see from this example, the two definitions are different because go is a strongly typed language, so the conversions between types must be cast, because int and MyInt1 are different types, so there is a compilation error.

But because MyInt2 just int an alias, is essentially a int type, so you can assign a value directly, no problem.

Type method

Each type can add its own method through the recipient's way, and we can see if the type alias is possible, and what methods are available.

 1234567891011121314151617 
 type  MyInt1 int  type  MyInt2 = int  func   (i MYINT1)  m1   ()   {fmt. Println ( "myint1.m1" )}func   (i MyInt2)  m2   ()   {fmt. Println ( "myint2.m2" )}func  main   ()   {var  i1 Myint1var  i2 myint2i1.m1 () i2.m2 ()} 

The example code above looks no problem, but when we compile we will prompt:

12
i2.m2 undefined (typetype int

There are 2 errors in this, one is that the hint type int does not have m2 this method, so we cannot call it, because MyInt2 essentially int .

The second error is that we can't int add a new method to a type, what does it mean? Because it int is a non-native type, we cannot add methods to it. In that case, let's customize a struct type to try.

12345678910111213141516171819202122
 type  User struct  {} type  MyUser1 usertype  MyUser2 = Userfunc   (i MyUser1)  m1   ()   {fmt. Println ( "myuser1.m1" )}func  Span class= "params" > (i MyUser2)  m2   ()   {fmt. Println ( "myuser2.m2" )}//blog:www.flysnow.org  //wechat:flysnow_org  func  main   ()   {var  i1 myuser1var  i2 myuser2i1.m1 () i2.m2 ()} 

Switch to a struct and run normally. Therefore, the alias of a locally defined type can still be added to the method. Now let's proceed to the above example to see an interesting phenomenon, I add the following code in the main function:

12
var i useri.m2 ()

Then run, discover, and run normally. Isn't it strange that we didn't define the method for the type User , ah, how can it be called? This is due to the type alias, which is MyUser2 exactly equivalent User , so MyUser2 defining the method equals User defining the method, and vice versa.

But not for the new defined type, MyUser1 because it is a completely new type, so User the method MyUser is not. There is no longer an example, you can try it yourself.

It is also important to note that, because it is MyUser2 completely equivalent User , User there are already methods that MyUser2 cannot be declared, and vice versa, if defined as follows:

12
 in the blockprevious declaration at./main.go:31:6

is actually the meaning of repeating the declaration, cannot repeat the declaration again.

Interface implementation

The above summary we can find, User and MyUser2 is equivalent, and one of the new methods, the other one will have. So based on this derivation, one implementation of an interface, the other will be implemented. Now verify:

1234567891011121314151617181920212223242526
 type  I interface  {m2 ()}type  User struct  {}type  MyUser2 = user< Span class= "function" >func   (i User)  m    {fmt. Println ( "USER.M" )}func   (i MyUser2)  m2   ()   {fmt. Println ( "myuser2.m2" )}func  Span class= "title" >main   ()   {var  u uservar  u2 myuser2var  i1 I =uvar  i2 I = U2fmt. Println (I1,I2)} 

Defines an interface, I from the code point of view, only MyUser2 implemented it, but our code in the demonstration, found User also implemented the interface I , so this verifies that our push is correct, and return if User an interface is implemented, then its type Alias will also implement this interface.

Many of the examples above are aliases of type structs, and we see if the type alias of interface interface is also equivalent.

1234567891011
type Interface {m ()} type MyI1 itype MyI2 = itypeintfunc(i MyInt)m (){fmt. Println ("MYINT.M")}

Defines an interface I that MyI1 is based on a I new type, MyI2 is a type alias, and I MyInt implements an interface I . Test the following.

12345678910111213141516
//blog:www.flysnow.org //wechat:flysnow_org  funcmain()  {//Assignment Implementation type MyIntvar i i = MyInt (0)var i1 MyI1 = MyInt (0)var< /c20> i2 MyI2 = MyInt (0)//Interface reciprocal assignment i = i1i = I2i1 = I2i1 = Ii2 = Ii2 = I1}

The above code is normal, this is the specific type of the preceding (struct,int, etc.) of the type alias is not the same, as long as the implementation of the interface, you can assign value to each other, whether you are the newly defined interface MyI1 , or the interface alias MyI2 .

Types of nesting

We all know that the two types of type alias are equivalent, but they are somewhat different when nested in a type.

 1234567891011121314151617181920 
 //blog:www.flysnow.org  //wechat: flysnow_org  func  main   ()   {my:=mystruct{}my. T2.M1 ()}type  T1 struct  {}func   (t T1)  m1   ()   {fmt. Println ( "t1.m1" )}type  T2 = t1type  mystruct struct  {T2} 

The example T2 is T1 the alias, but we put the T2 nested in MyStruct , when the call can only be T2 called by this name, and cannot pass T1 , will not prompt this field. The reverse is the same.

This is because T1 , T2 two names, although they are equivalent, they are equivalent types with two different names, so when the type is nested, it is two fields.

Of course we can put T1 , T2 at the same time embedded MyStrut in, to make separate calls.

123456789101112
//blog:www.flysnow.org //wechat:flysnow_org  funcmain()  {my:=mystruct{}my. T2.M1 () My. T1.M1 ()}typestruct {t2t1}

The above is also able to run normally, proving that this is a field of the same type with two different names.

Let's do an interesting experiment and main change the code of the method to the following:

123456
Blog:www.flysnow.org//wechat:flysnow_orgfunc Main () {my:=mystruct{}my.m1 ()}

Guess if you can compile and run it properly? The promise may unexpectedly, is unable to compile normally, prompts the following:

1
./main.go:25:4: Ambiguous selector my.m1

In fact, think very simple, do not know which to call, too vague, can not match, or the use T1 of m1 , T2 or m1 . This result is not limited to the method, the field is also the same, not limited to the type Alias,type defintion is also the same, as long as there are duplicate methods, fields, there is this hint, because do not know which to choose.

Type loop

Type alias declaration, be sure to pay attention to the types of loops, do not produce a loop, once produced, will compile does not pass, then what is the type of loop it. If type T2 = T1 , then T1 absolutely can not direct, or indirect reference to T2 , once there, will type loop.

1234567
type T2 = *t2type T2 = mystructtypestruct {t1t2}

Both of these definitions are type loops, and we want to avoid the emergence of this definition in our own use.

Byte and Rune

These two types are int8 aliases, one is the alias of the Int32, and they are defined before go 1.9.

123
type byte byte type Rune Rune

Now that go 1.9 has the new feature of type alias, their definition becomes the following:

123
type byte uint8 type Rune Int32

Yes, it's very convenient and concise.

Exporting types that are not exported

Type alias also has a feature to export a type that is not exported.

 12345678910111213141516171819 
  Package  Lib//blog:www.flysnow.org  //wechat:flysnow_org  type  user struct  {name  Email string }func   (u user)  getname   ()  string   {return  U.name}func   (u user)  getemail   ()  string   {return  u. Email}//to export this user to user  type  user = user 

useris a non-exported type and cannot be accessed by another package, but we can type User = user define one through, User so that this User can be accessed by other package, you can use user the fields and methods of the type export, the Email fields and GetEmailmethod, and the fields and methods that are not exported name getName are not used by other package.

Summary

The definition of type alias is essentially the same type, just an alias, how the source type is used, how the alias type is used, and all methods, fields, etc. of the source type are preserved.

This article for the original article, reprint annotated source, welcome to sweep the code to pay attention flysnow_org to the public number or website http://www.flysnow.org/, the first time to see the following wonderful articles. Feel good, and share to friends Circle, thank you for your support.

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.