Preface
Have you heard of it?Go
Are functions in languages first-class citizens? If not, then congratulations, this article will take you to unveil this mystery. If you already understand this concept, do you know why?Go
Are functions in language called first-class citizens? Whatever your answer is, by reading this article, you will gain a deeper understanding of the concept.
Ready? Prepare a cup of your favorite coffee or tea and find out with this article.
First class citizen
In a given programming language design, a first-class citizen is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, and assigned to a variable.
What is a first-class citizen? The above citation is from Wikipedia, which means literally: "In a given programming language design, a first-class citizen refers to an entity that supports all operations that are usually available for other entities. These operations usually include passing as parameters, returning from functions, and assigning values to variables."
It seems a bit difficult to understand in literal translation, it doesn't matter, we can understand it in a simpler way: "In programming language design, elements called first-class citizens can freely perform common operations, such as passing as parameters, returning from functions and assigning values to variables."
existGo
In languages, functions have these characteristics, they can be assigned to variables, passed as parameters, and can be used as return values of functions.
Example of practical application of functions as first-class citizens
When we understandGo
After why functions in language are regarded as first-class citizens, let us explore its practical application as first-class citizens.
Assign value to variables
existGo
In languages, a function is a type that can be like other types (such asint64
、string
etc.) is assigned to a variable, which means we can create a variable, assign the function to it, and then call the function through that variable.
Assign normal functions to variables
We can assign a normal function to a variable so that the function can be called through the variable. Here is a sample code:
import ( "fmt" ) func SayHello(s string) { (s) } func main() { sayHelloFunc := SayHello sayHelloFunc("Hello, I'm Chen Mingyong") // Hello, I'm Chen Mingyong}
In the above example, first we define a normal functionSayHello(s string)
, this function accepts a string parameters
, and use it in the function bodyFunction prints strings;
Then inmain
In the function, we assign the function to the variablesayHelloFunc
, Through this variable, we can callSayHello
Function, implement the same function. This method can be used when dynamically selecting functions is required to make the code moreflexibleandReusable。
Create anonymous functions and assign values to variables
In addition to assigning normal functions to variables, we can also create anonymous functions and assign them to variables. Here is a sample code:
import ( "fmt" ) func main() { sayHelloFunc := func(s string) { (s) } sayHelloFunc("Hello, I'm Chen Mingyong") // Hello, I'm Chen Mingyong}
In the above code, we usefunc
The keyword creates an anonymous function, which also accepts a string parameter.s
, and use it in the function bodyThe function prints a string; then we assign the anonymous function to
sayHelloFunc
Variable. passsayHelloFunc
Variables, we can call anonymous functions and pass in corresponding parameters to achieve the same function.
Anonymous functions are created in a flexible and concise way, especially suitable for one-time function requirements or scenarios where functions need to be defined in different contexts.
Passed as parameters
existGo
In language, functions can be passed as function parameters to other functions, which makes functions more flexible in operation and combination. Let’s take a look at an example of time conversion;
import ( "fmt" "time" ) // ApplyFormatTimeToStringFunc converts the time type into the corresponding string type according to the parameters t and operation. The format of the string is determined by the parameter operation// If parameter t is zero, an empty string is returnedfunc ApplyFormatTimeToStringFunc(t , operation func(t ) string) string { if () { return"" } return operation(t) } // FormatTimeToString converts time into yyyy-MM-ddfunc FormatTimeToString(t ) string { return () } // FormatDateTimeToString converts time into yyyy-MM-dd HH:mm:ssfunc FormatDateTimeToString(t ) string { return () } func main() { // yyyy-MM-dd formatTimeToString := ApplyFormatTimeToStringFunc((), FormatTimeToString) (formatTimeToString) // 2023-07-18 // yyyy-MM-dd HH:mm:ss formatDateTimeToString := ApplyFormatTimeToStringFunc((), FormatDateTimeToString) (formatDateTimeToString) // 2023-07-18 00:00:00 }
In the above example, first we define aApplyFormatTimeToStringFunc
Function, this function receives a time type parametert
and a function type parameteroperation
, according to parameterst
andoperation
, convert the time type into a string type, the format of the string is from the parametersoperation
Decide;
Then define two operation functionsFormatTimeToString
andFormatDateTimeToString
, these two functions convert time toyyyy-MM-dd
andyyyy-MM-dd HH:mm:ss
format;
Finally atmain
In the function, we pass different operation functions as parameters toApplyFormatTimeToStringFunc
Function to format the current time. By passing the function as a parameter to another function, dynamically changing the behavior of the function allows us to choose different formatting methods to process the time according to our needs, and improve the flexibility and reusability of the code.
Return value as function
existGo
In languages, in addition to assigning values to variables and passing them as parameters, functions can also be used as the return value of the function. Here is the sample code:
import ( "fmt" ) func CreateDialogueFormatter(name string) func(string) string { returnfunc(s string) string { return ("[%s]: ", name) + s } } func main() { DialogueOfCmy := CreateDialogueFormatter("Chen Mingyong") (DialogueOfCmy("Hello")) // [Chen Mingyong]: Hello DialogueOfGopher := CreateDialogueFormatter("Gopher") (DialogueOfGopher("Hello")) // [Gopher]: Hello}
In the above example, first we defineCreateDialogueFormatter
function, this function receives aname
Parameters, used to set the conversational nickname and return a customizable dialogue function;
Then inmain
In the function, by callingCreateDialogueFormatter
Functions and pass in different nicknames, you can create multiple conversation functions for different conversational people.
By taking the function as the return value, we can generate the function dynamically at runtime, making the function more flexible and customizable.
summary
Functions as first-class citizens inGo
It is very important in languages. With its three major features, we can implement advanced function programming and improve code flexibility and reusability.
The above is a detailed article that will take you to explore the first-class functions in Go language. For more information about Go language functions, please follow my other related articles!