Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rethink the use of pointers or values as a function parameters #8

Open
trco opened this issue Aug 18, 2024 · 0 comments
Open

Rethink the use of pointers or values as a function parameters #8

trco opened this issue Aug 18, 2024 · 0 comments
Assignees

Comments

@trco
Copy link
Owner

trco commented Aug 18, 2024

In Go, deciding whether to use a pointer or a value as a function parameter depends on several factors, such as performance considerations, whether the function needs to modify the argument, and the size of the data being passed. Here's a breakdown of when to use pointers versus values:

When to Use Pointers

Modification of the Argument

Mutating Data: If the function needs to modify the data in the argument and have those changes reflected outside the function, you should pass a pointer.

Example

func increment(num *int) {
    *num++
}

Large Structs or Complex Data Types

Performance Consideration: Passing large structs or complex data types by value can be expensive because Go will make a copy of the data. Using a pointer avoids this copying, leading to better performance.

Example

type LargeStruct struct {
    Field1 [1000]int
    Field2 string
}

func processLargeStruct(ls *LargeStruct) {
    // Do something with ls
}

Nilable Arguments

Optional Arguments: Pointers can be used to represent the absence of a value (using nil). This is useful when a function parameter is optional.

Example

func printMessage(msg *string) {
    if msg != nil {
        fmt.Println(*msg)
    } else {
        fmt.Println("No message provided")
    }
}

Avoiding Slices and Maps Copying

Slices and Maps Are References: While slices and maps are already reference types (passing them by value passes a reference), you might still use a pointer if you want to pass a pointer to the slice or map itself, not just a reference to the underlying data.

Example

func modifySlice(s *[]int) {
    *s = append(*s, 10)
}

When to Use Values

Small Structs or Primitive Types

No Need for Pointers: For small structs or basic data types (like int, float, string, etc.), passing by value is usually more straightforward and avoids potential issues related to pointer manipulation.

Example

func printInt(num int) {
    fmt.Println(num)
}

Immutability or Safety

Avoiding Side Effects: When you want to ensure that the function does not modify the argument or when immutability is important, passing by value is safer.

Example

func calculateSquare(num int) int {
    return num * num
}

Copying for Concurrency

Thread Safety: If the data is passed to goroutines and you don’t want to deal with synchronization issues, passing by value can be safer as it prevents shared mutable state.

Example

func processValue(val int) {
    go func(v int) {
        // Use v safely inside the goroutine
    }(val)
}

General Guidelines

  • Use pointers when you need to modify the argument, avoid unnecessary copies, or represent an optional value.
  • Use value types when you want immutability, thread safety, or when dealing with small data that is cheap to copy.

These guidelines help you balance performance with safety and clarity in your Go programs.

@trco trco self-assigned this Aug 18, 2024
@trco trco changed the title Rethink usage of pointers to Rethink the use of pointers or values as a function parameters Aug 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant