- Function definition with arguments and a return type - how to pass arguments to a function and express the return type.
- Function overloading - how to provide multiple different implementations with different sets of arguments
- Default or Optional Arguments - how to provide defaults or express optionality in arguments
- Lambda Functions - defining a lambda function
- Lambda Function Capture - using local in-scope variables inside the lambda function
- Function Type Parameter (Generics) - how to define a function with one or more types as an argument
- Function Type Parameter Constraints - how to define a constraint on the type parameter
Functions
Change TopicGo Language
TypeScript Functions
Function Definition with Arguments and Return Type
Golang requires explicit type declarations for function parameters and return values.
func add(x int, y int) int { return x + y } func greet(name string) string { return fmt.Sprintf("Hello, %s!", name) }
- Parameters and return types are explicitly defined.
- Multiple parameters of the same type can be grouped:
func add(x, y int) int
. - Functions can return multiple values.
func divide(a, b int) (int, int) { return a / b, a % b }
Function Definition with Arguments and Return Type
TypeScript allows specifying argument types and return types explicitly in function definitions.
function add(x: number, y: number): number { return x + y; } const greet = (name: string): string => `Hello, ${name}!`;
x: number, y: number
: Defines parameter types.: number
after()
specifies the return type.
Function Overloading
No function overloading, but can emulate it with interfaces
import ( "fmt" ) func Add(x, y interface{}) interface{} { switch x.(type) { case int: return x.(int) + y.(int) case string: return x.(string) + y.(string) default: return nil } } func main() { fmt.Println(Add(5, 10)) // 15 fmt.Println(Add("Hello, ", "World!")) // "Hello, World!" }
Function Overloading
Function overloading processed at runtime
function add(x: number, y: number): number; function add(x: string, y: string): string; function add(x: any, y: any): any { return x + y; } console.log(add(5, 10)); // 15 console.log(add("Hello, ", "World!")); // "Hello, World!"
Default Arguments
Not supported by Go, but you can use variadic parameters
func greet(name string, greetings ...string) { greeting := "Hello" if len(greetings) > 0 { greeting = greetings[0] } fmt.Printf("%s, %s!\n", greeting, name) } func main() { greet("Alice", "Hi") // Uses "Hi" greet("Bob") // Uses default "Hello" }
Or simulate it with a struct:
type Config struct { Greeting string Name string } func greet(cfg Config) { greeting := cfg.Greeting if greeting == "" { greeting = "Hello" } fmt.Printf("%s, %s!\n", greeting, cfg.Name) } func main() { greet(Config{Name: "Alice", Greeting: "Hi"}) greet(Config{Name: "Bob"}) // Greeting defaults to "Hello" }
Function Default Arguments
function doIt(b: number, a = 1) { return b / a; } console.log("DoIt " + doIt(10) + " " + doIt(10, 2));
Lambda Function
In Go, lambda functions (also called anonymous functions) are defined inline without a name and can be immediately invoked or assigned to a variable.
Example:
func main() { // Immediately invoked function func() { fmt.Println("Hello from a lambda function!") }() // Assigning a lambda function to a variable add := func(a, b int) int { return a + b } fmt.Println("Sum:", add(3, 4)) // Output: Sum: 7 }
Lambda Functions
const doIt = (b: number, c: number) => a * b; console.log("DoIt " + doIt(10, 5));
Lambda Functions Capturing Values
Lambda functions in Go capture variables from their surrounding scope by reference, meaning changes in the function affect the original variable.
Example:
func main() { x := 10 // Lambda function capturing 'x' from outer scope modifyX := func() { x += 5 // Modifies x from the outer scope } modifyX() // Call lambda function fmt.Println("Modified x:", x) // Output: Modified x: 15 }
However, since Go passes function parameters by value (unless using pointers), lambda functions do not automatically modify arguments unless explicitly passed by reference:
func main() { x := 10 // Lambda function that takes an argument (no capture) increment := func(n int) { n += 5 // This modifies only the local copy of 'n' } increment(x) fmt.Println("Unchanged x:", x) // Output: Unchanged x: 10 }
To modify x
, pass it by reference using a pointer:
func main() { x := 10 // Lambda function using pointer to modify the actual variable increment := func(n *int) { *n += 5 } increment(&x) fmt.Println("Modified x:", x) // Output: Modified x: 15 }
Lambda Function Capture
function createCounter(): () => number { let count = 0; // This variable is captured by the closure return () => { count += 1; return count; }; } const counterA = createCounter(); console.log(counterA()); // 1 console.log(counterA()); // 2 const counterB = createCounter(); console.log(counterB()); // 1 (separate closure) console.log(counterA()); // 3 (original closure still intact)
function makeMultiplier(factor: number): (input: number) => number { // factor is captured by the inner function return (input: number) => input * factor; } const double = makeMultiplier(2); const triple = makeMultiplier(3); console.log(double(5)); // 10 console.log(triple(5)); // 15
Function Generics
import "fmt" func identity[T any](value T) T { return value } func main() { fmt.Println(identity(42)) // 42 fmt.Println(identity("Hello")) // Hello }
Function Generics
function identity<T>(value: T): T { return value; } console.log(identity<number>(42)); // 42 console.log(identity<string>("Hello")); // "Hello"
Function Generics with Constraints
And with constraints:
import "fmt" // Constraint: only types that support the + operator type Number interface { int | float64 } func add[T Number](a, b T) T { return a + b } func main() { fmt.Println(add(5, 10)) // 15 fmt.Println(add(5.5, 2.3)) // 7.8 }
Function Generics Constraint
And with a constraint:
function getLength<T extends { length: number }>(arg: T): number { return arg.length; } console.log(getLength("Hello")); // 5 console.log(getLength([1, 2, 3])); // 3