Functions

Change Topic
  • 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

Go 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