This article discusses the optional parameters and function types of Golang functions, and how to use optional function types to implement optional modes. At the same time, using constructors as examples, a powerful constructor with optional parameters is implemented, making the code more intuitive, flexible and expandable.
Start with demand
Optional parameters pass additional parameters to the function to extend or modify its behavior. The following example uses optional functions to create a house type:
h := NewHouse( WithConcrete(), WithoutFireplace(), )
NewHouse
is a constructor,WithConcrete
andWithoutFireplace
is an optional parameter to pass in the constructor to modify its return value. Details belowWithConcrete
andWithoutFireplace
Optional functional functions, sometimes they are more useful than normal function parameters.
Define the constructor
First define the structure to utilize optional functions:
type House struct { Material string HasFireplace bool Floors int } // `NewHouse` is a constructor function for `*House` func NewHouse() *House { const ( defaultFloors = 2 defaultHasFireplace = true defaultMaterial = "wood" ) h := &House{ Material: defaultMaterial, HasFireplace: defaultHasFireplace, Floors: defaultFloors, } return h }
House
It may be made of different materials, with multiple layers, and may include a fireplace.NewHouse
Constructor returnsHouse
Pointer, all attributes include default values. Under normal circumstances, first constructHouse
, and then modify the attribute value according to different needs. Using function optional parameters, you can pass a set of modifier functions to the constructor.
Define optional functions
First define the function type, acceptHouse
Type pointer:
type HouseOption func(*House)
This is the signature of the optional function. The following defines some optional functions for modification*House
Example:
func WithConcrete() HouseOption { return func(h *House) { = "concrete" } } func WithoutFireplace() HouseOption { return func(h *House) { = false } }
Each function above is an optional constructor, returns another function with*House
Parameter, no return value. We see that the returned function has been modified*House
The attributes of the instance. Other optional function types can also be implemented to modify parameter instance properties. The following function returns optional functions to modify the floor:
func WithFloors(floors int) HouseOption { return func(h *House) { = floors } }
Enhanced constructor
Now combine optional function functions and constructors:
// NewHouse now takes a slice of option as the rest arguments func NewHouse(opts ...HouseOption) *House { const ( defaultFloors = 2 defaultHasFireplace = true defaultMaterial = "wood" ) h := &House{ Material: defaultMaterial, HasFireplace: defaultHasFireplace, Floors: defaultFloors, } // Loop through each option for _, opt := range opts { // Call the option giving the instantiated // *House as the argument opt(h) } // return the modified house instance return h }
The constructor accepts any number of optional function functions as parameters. After the House property is initialized for the first time, the optional function function is run accordingly to modify the property value.
Going back to the beginning example, you can now implement a constructor call with optional parameters:
h := NewHouse( WithConcrete(), WithoutFireplace(), WithFloors(3), )
Advantages of optional modes
The above discusses how to implement optional modes, and here is a summary of its advantages.
Intuitive and clear
Compared to displaying modified object properties:
h := NewHouse() = "concrete"
It can be directly implemented using constructors:
h := NewHouse(WithConcrete())
This is clearer, without specifying string values, avoiding typing errors and exposing *house internal details.
Support extensions
Optional mode supports extensions, always supporting different optional function parameters to pass into the constructor. For example, since the floor of the house can be any integer, we provide specific values as parameters to pass into the constructor:
h := NewHouse(WithFloors(4))
Parameter order
The use of optional mode is independent of the parameter order and has great flexibility compared to normal parameters; and, any optional parameters can be provided, and all parameters must be provided compared to normal parameters.
// What `NewHouse` would look like if we used // regular function arguments // We would always need to provide all three // arguments no matter what h := NewHouse("concrete", 5, true)
This is the end of this article about using Golang optional parameters to implement optional modes. For more relevant Golang optional parameters, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!