introduction
The most basic concept of object-oriented programming language is classes (class
),butGo
The language does not have a class concept, so it is usedGo
When developing languages, we usually usestruct(structure)
To simulate classes in object-oriented.
Classes are usually constructed by a constructor (constructors
) to initialize the properties in the instance (object) of the class, butGo
ofstruct
There is no mechanism like constructing methods, so how to initialize itstruct
What about the instance of type?
Let's introduce several creationsstruct
Methods of type variables.
Literal
Create and initialize astruct
The easiest and most direct way to use variables isstruct
Literal:
//app/ package school type Student struct { ID int Name string Score int Grade string } // package main func main() { s := &Student{ ID: 1, Name: "Xiao Ming", Score: 90, Grade: "Class 2 of High School", } }
But sometimes we just need a temporarystruct
For type, anonymous can be usedstruct
:
func main() { s := struct { ID int Name string Score int Grade string }{ ID: 1, Name: "Xiao Ming", Score: 90, Grade: "Second Grade in High School", } }
Use built-in new function
In addition to literality, useGo
The built-in new function can also create astruct
Variables, but this method requiresstruct
Assign initial values to each field:
func main(){ s := new(Student) = 1 = "Xiao Ming" = 90 = "Class 2 of High School" }
Constructor
We've said it beforeGo
Languagestruct
There is no constructor, but we can customize the function to initialize itstruct
, the advantage of custom functions is:
- The purpose of reuse can be achieved.
- Can be packaged.
- You can verify that the initialization value is within the allowed range.
Generally, our custom constructors areNew
Prefix, for example:
package school type student struct { ID int Name string Score int Grade string } func NewStudent(ID int, Name string,Score int Grade string) *Student { if ID < 0{ panic("ID cannot be less than 0") } if Score < 0 || Score > 100{ panic("Score must be between 0 and 100") } s := new(Student) = 1 = "Xiao Ming" = 90 = "Class 2 of High School" return s } package main import "app/school" func main(){ s := (1,"Xiao Ming",90,"Class 2 of High School") }
In the above example, we customizedNewStudent()
The function can be reused in other packages to initializestruct
,WillStudent
Change tostudent
, so that other packages cannot be accessed directlystudent
The structure achieves the effect of packaging, andNewStudent()
In the function, we can also verify whether the parameters are reasonable.
Of course, custom constructors must also beNew
prefixed, such as standard libraryos
In the package, you can use it when initializing the file handle.Open()
,Create()
andOpenFile()
Wait for the function to initialize:
//The file code of the os packagefunc Open(name string) (*File, error) { return OpenFile(name, O_RDONLY, 0) } func Create(name string) (*File, error) { return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666) } func OpenFile(name string, flag int, perm FileMode) (*File, error) { (name) f, err := openFileNolog(name, flag, perm) if err != nil { return nil, err } = flag&O_APPEND != 0 return f, nil }
Constructors that support variadic parameters
In the above example, we can useNewStudent()
Function creates astudent
Variable of type, but the order and number of parameters of this constructor are fixed, if there are multiple places to callNewStudent()
Function, when a new parameter is added to the function, all codes called to the function must be adjusted.
We can optimize our constructor again, using the number and order of its parameters that are variable:
package school type student struct { ID int Name string Score int Grade string } type StudentOptionFunc func(*student) func WithID(id int) StudentOptionFunc { return func(s *student) { = id } } func WithName(name string) StudentOptionFunc { return func(s *student) { = name } } func WithScore(score int) StudentOptionFunc { return func(s *student) { = score } } func WithGrade(grade string) StudentOptionFunc { return func(s *student) { = grade } } func NewStudent(opts ...StudentOptionFunc) *student { s := &student{} for _, opt := range opts { opt(s) } return s }
In the example above, the constructorNewStudent()
The parameters are indefinitely longStudentOptionFunc
A function of type can be regarded as a slice containing multiple functions,NewStudent()
The function traverses the slice internally and initializes its own fields through each function in the slice.
Next, in the call, we can call without being affected by the number and order of parameters.NewStudent()
Function:
package main import ( "app/school" "fmt" ) func main() { s1 := ( ("Xiao Ming"), (90), (1), (""), ) s2 := ( ("Little Flower"), (90), ) }
Promise plan
The above demonstrates two custom constructors. One is to initialize the number and order of parameters completely fixed. This method is too rigid, while the other is to pass the order and number of parameters freely. This method is too free, because we can think of a compromise solution, that is, to combine the two methods:
func NewStudent(id int, Name string, opts ...StudentOptionFunc) *student { s := &student{ID: id, Name: Name} for _, opt := range opts { opt(s) } return s }
summary
Several initializations introduced abovestruct
There is no difference between good and bad in the way, choose the way you like to initialize itstruct
Just variables.
This is the end of this article about the detailed explanation of the method of Go initializing Struct. For more related content on Go initializing Struct, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!