Basic series of Go: Export and exposure of struct

Source: Internet
Author: User
Struct export and exposure problems about struct Export

Whether the struct attribute is exported also follows the case-sensitive principle: the first letter is exported in upper case, and the first letter is not exported in lower case.

Therefore:

  1. If the first letter of the struct name is lower-case, this struct will not be exported. Fields in it are not exported, even if the first letter is an upper-case field name..
  2. If the first letter of a struct name is capitalized, struct will be exported, but only fields with the first letter in it will be exported. fields with the first letter in lowercase will not be exported..

That is to say, the export of struct is mixed.

But not absolutely,If struct is nested, fields with uppercase letters can be accessed even if the initial letter of the struct name is lower-case..

For example:

type animal struct{    name string    Speak string}type Horse struct {    animal    sound string}

The nested animal in horse starts with a lowercase letter, but horse can be exported. Therefore, horse struct can be used in other packages. Other packages can also access the Speak attribute in animal.

In many cases, the horse name is insecure, because it indicates exporting the struct of horse to other packages, that is, exposing the horse, you can directly open the "black box" of horse ".

But if you do not export horse, how can you build a horse instance in other packages? See below.

Do not expose struct

In many cases, struct (such as animal) in a package (such as ABC) should not be directly exposed to other packages. Exposure means that the "black box" is opened ", therefore, struct starts with a lowercase letter and does not export it.

At this time, the animal of the ABC Package is built in other external packages and cannot be directly implemented through the following methods:

  • var xxx abc.animal
  • new(abc.animal)
  • &abc.animal{...}
  • abc.animal{...}

For example, the following is incorrect:

// ABC/ABC. go file content: Package abctype animal struct {name string speak string} // test. go content: Package mainimport ". /ABC "func main () {// all errors var T1 ABC. animal t2: = new (ABC. animal) T3: = & ABC. animal {} T4: = ABC. animal {}}

So how can we build a hidden struct instance? In this case, you can write an export function in the ABC Package to build a struct instance. For example:

// ABC/ABC. go file content: Package abctype animal struct {name string speak string} func newanimal () * animal {A: = new (animal) return a} // test. go content: Package mainimport ("FMT "". /ABC ") func main () {T1: = ABC. newanimal () // t1.name = "Haha" // The name attribute t1.speak = "hhhh" FMT cannot be accessed. println (t1.speak )}

The above code is normal. In the main package, newanimal () can be used to build unexported animal struct In the ABC Package. Note: In newanimal (), the new () function is used to construct the instance. It returns the instance pointer. As for how to construct the instance, you can fully meet your needs, however, for the struct type, pointers are generally used, that is, new () can be generalized completely.

Because the name field in animal is not exported, the name attribute of an animal instance cannot be accessed in the outside world even if an animal instance is created through newanimal, therefore, the name field cannot be assigned a value. In other words, the name attribute is always the initialized 0 value.

Therefore, to customize the name attribute when building an instance, you must specify the parameter set to the name attribute on the constructor newanimal. Modify the newanimal () function:

func NewAnimal(name string) *animal{    a := new(animal)    a.name = name    return a}

Then, create an animal instance in another package:

t1 := abc.NewAnimal("longshuai")

Although the animal instance built in other packages already has the name attribute, it still cannot be accessed. Therefore, you can re-write an export method in the ABC Package to obtain the name attribute of the instance:

// ABC/ABC. Go: func (A * animal) getname () string {return a. name}

Therefore, the external package can use this export method to obtain the Instance name attribute:

t1 := abc.NewAnimal("longshuai")fmt.Println(abc.GetName())

In fact, when newanimal () constructs an object, you do not need to pass the name parameter, but write a special method like getname () to set the name attribute of the instance. Rewrite the code in ABC/ABC. Go:

func NewAnimal() *animal{    a := new(animal)    return a}func (a *animal) SetName(name string){    a.name = name}

Now, animal struct in ABC/ABC. Go is completely hidden.

Note that the above setter Class MethodSetName()It cannot be modified by two or more threads at the same time. Otherwise, the value will be overwritten and thread security issues may occur. You can use the sync package, goroutine, and channel to solve this problem.

Method export in nested struct

When the internal struct is nested into the external struct, the internal struct method is also nested, that is, the external struct has the internal struct method.

However, note the case sensitivity of the method. Because the inside and outside struct are in the same packageBuild an external struct instance directly within the package, and an external struct instance can directly access all methods of the internal struct. However, if an external struct instance is built in another package, the instance will not be able to access the internal struct method with the first letter and lowercase letter..

The following is a test in the same package. External instances can directly call the internal struct method:

Package mainimport ("FMT") type person struct {name string age int} // method not exported func (p * person) Speak () {FMT. println ("speak in person")} // export method func (p * person) Sing () {FMT. println ("sing in person")} // admin exportedtype admin struct {person salary int} func main () {A: = new (Admin). speak () // normal output. sing () // normal output}

Execution resulta.speak()Anda.Sing()All are output normally.

The tests in different packages are as follows. struct is defined in the ABC/ABC. Go file and main is in test. Go. Their directory structure is as follows:

$ tree ..├── abc│   └── abc.go├── test.go

The content of ABC/ABC. Go is:

Package abcimport "FMT" // unexported persontype person struct {name string age int} // unexported method func (p * person) Speak () {FMT. println ("speak in person")} // export method func (p * person) Sing () {FMT. println ("sing in person")} // admin exportedtype admin struct {person salary int}

The content of test. Go is:

Package mainimport ". /ABC "func main () {A: = new (ABC. admin) // the following error //. speak () // The following is normal. sing ()}

The execution result is,a.speak()Error reported,a.Sing()Normal.

Basic series of Go: Export and exposure of struct

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.