<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ezra Natanael on Medium]]></title>
        <description><![CDATA[Stories by Ezra Natanael on Medium]]></description>
        <link>https://medium.com/@ezrantn?source=rss-7f8e7fb32b39------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*1585s_hrlViz2U0zDWdB_A.png</url>
            <title>Stories by Ezra Natanael on Medium</title>
            <link>https://medium.com/@ezrantn?source=rss-7f8e7fb32b39------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 04:03:48 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ezrantn/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Understanding and Preventing Nil Pointer Dereference Panics in Go]]></title>
            <link>https://medium.com/@ezrantn/understanding-and-preventing-nil-pointer-dereference-panics-in-go-1b0d341fa6b0?source=rss-7f8e7fb32b39------2</link>
            <guid isPermaLink="false">https://medium.com/p/1b0d341fa6b0</guid>
            <category><![CDATA[go]]></category>
            <dc:creator><![CDATA[Ezra Natanael]]></dc:creator>
            <pubDate>Sat, 25 May 2024 12:54:41 GMT</pubDate>
            <atom:updated>2024-05-25T12:54:41.411Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*GYfOrFWY1jfM0sBW" /><figcaption><a href="https://unsplash.com/photos/a-close-up-of-a-computer-screen-with-a-sign-on-it-O_Xy25Dj7Mo">https://unsplash.com/photos/a-close-up-of-a-computer-screen-with-a-sign-on-it-O_Xy25Dj7Mo</a></figcaption></figure><p>For those who code in Go, you might encounter a common error: the nil pointer error. This error can be confusing for beginners and even for those with previous programming experience. But don’t worry, I’ll explain everything about the nil pointer error and how to prevent it.</p><p>Imagine your computer’s memory as a big storage unit with many compartments. Each compartment has a unique number, which we call an address. A pointer is like a note that you write down one of these addresses on, so you can quickly find a specific compartment again.</p><p>A nil pointer is like a blank note — it doesn’t have any address written on it. It points to nowhere, meaning it doesn’t tell you where to find a compartment in memory.</p><p>Dereferencing a pointer is like reading the note to see which compartment it points to, then going to that compartment to get whatever is stored there.</p><p>If you try to dereference a nil pointer (read a blank note), you end up with no address to go to. In Go, doing this causes the program to panic. A panic is like the program throwing up its hands and saying, “I don’t know what to do!” This panic stops the program from running and causes it to crash.</p><p>So, a nil pointer dereference panic happens when you try to use a pointer that points to nowhere. Since there’s no valid address to access, Go can’t continue and shuts down the program to prevent further errors.</p><p>Let see some code in action!</p><p>First, I’m going to demonstrate a code <strong>without</strong> a pointer:</p><pre>package main<br><br>import (<br> &quot;fmt&quot;<br>)<br><br>// declare a Person struct with 2 values Name and Age<br>type Person struct {<br> Name string<br> Age int<br>}<br><br>// Accessing Person struct to see the value<br>func main() {<br> var person Person<br> fmt.Println(person.Name)<br> fmt.Println(person.Age)<br>}<br><br>// Output:<br>// <br>// 0</pre><p>If you run the code above, you won’t see an error. It just outputs an empty string and zero in the console, right? So why does that happen? When you run the code, the output is an empty string and zero because person.Name is initialized to the default value for a string, which is an empty string. Similarly, person.Age is set to zero because that is the default value for an integer.</p><p>So the conclusion is: if we declare a struct and access the values in the struct <strong>without</strong> using a pointer, and the values haven’t been initialized, we can do that because Go will use the default value of each data type.</p><p>Now let’s see some code <strong>with</strong> pointer:</p><pre>package main<br><br>import (<br> &quot;fmt&quot;<br>)<br><br>// declare a Person struct with 2 values Name and Age<br>type Person struct {<br> Name string<br> Age int<br>}<br><br>// Accessing Person struct with a pointer to see the value<br>func main() {<br> var person *Person<br> fmt.Println(person.Name)<br> fmt.Println(person.Age)<br>}<br><br>/* Output:<br>panic: runtime error: invalid memory address or nil pointer dereference<br>[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47afba]<br><br>goroutine 1 [running]:<br>main.main()<br>        /home/ezrantn/Documents/Coding/Golang/pointers/main.go:14 +0x1a<br>exit status 2<br>*/<br></pre><p>Since Person is a nil pointer (not pointing to any valid memory address), attempting to access its fields (Name and Age) results in a nil pointer dereference. This means Go doesn’t know the values of Name and Age since it hasn’t been initialized.</p><p>Using a pointer without proper initialization leads to a “nil pointer dereference” error. This happens because the pointer doesn’t have a valid memory address to access.</p><p>But if we decide to initialize both values with the help of a function, like this:</p><pre>package main<br><br>import (<br> &quot;fmt&quot;<br>)<br><br>type Person struct {<br> Name string<br> Age int<br>}<br><br>// function to create new person returning a pointer of Person<br>func createNewPerson(name string, age int) *Person {<br> return &amp;Person{<br>  Name: name,<br>  Age: age,<br> }<br>}<br><br>func main() {<br> // initialized both values<br> person := createNewPerson(&quot;John&quot;, 20)<br><br> fmt.Println(person.Name)<br> fmt.Println(person.Age)<br>}<br><br>/* Output:<br>John<br>20<br>*/</pre><p>The provided code demonstrates this issue and fixes it by introducing the createNewPerson function. This function takes a name and age, creates a Person struct, initializes its fields, and returns a pointer to the newly created struct.</p><p>By using this function in main, we ensure the person pointer points to a valid memory location with the Person data. This allows you to access the Name and Age fields successfully.</p><p>If you’re wondering when you should use pointers and when you shouldn’t, you should know that in Go, pointers are used in a variety of contexts to efficiently manage memory and enable specific programming paradigms. Here are some key circumstances when pointers are especially useful.</p><ol><li>Modifying Function Arguments:</li></ol><p>Pointers are often used to allow functions to modify their arguments. By passing a pointer to the argument, the function can change the value of the original variable, not just a copy of it.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>func modifyValue(val *int) {<br>    *val = 100<br>}<br><br>func main() {<br>    num := 10<br>    modifyValue(&amp;num)<br>    fmt.Println(num) // Output: 100<br>}</pre><p>2. Avoiding Copies of Large Structures:</p><p>When dealing with large structs, passing them by value can be inefficient as it involves copying the entire structure. Using pointers can avoid this overhead by passing references instead of copying the data.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>type LargeStruct struct {<br>    Data [1000]int<br>}<br><br>func processStruct(ls *LargeStruct) {<br>    // Process the struct<br>    ls.Data[0] = 1 // Example modification<br>}<br><br>func main() {<br>    ls := LargeStruct{}<br>    processStruct(&amp;ls)<br>    fmt.Println(ls.Data[0]) // Output: 1<br>}</pre><p>3. Implementing Methods that Modify the Receiver:</p><p>Pointers are used to define methods that modify the receiver’s state. If a method needs to modify the receiver, it must have a pointer receiver.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>type Counter struct {<br>    value int<br>}<br><br>func (c *Counter) Increment() {<br>    c.value++<br>}<br><br>func main() {<br>    c := &amp;Counter{}<br>    c.Increment()<br>    fmt.Println(c.value) // Output: 1<br>}</pre><p>The three most common and important uses of pointers in Go are these three contexts. There are many situations in which pointers should be used, so I recommend reading up on them <a href="https://gobyexample.com/pointers">here</a>. They provide more powerful and flexible programming and aid in performance optimization.</p><p>Thus, the key query is: How can I keep my code from causing nil pointer dereference? We’ll go over some advice I have for you together.</p><p>Preventing nil pointer dereference in Go is crucial to avoid runtime panics and ensure robust code. Here are some best practices along with code examples to handle and prevent nil pointer dereferences effectively:</p><ol><li>Check For nil Before Dereferencing:</li></ol><p>Before accessing a pointer’s value, always check if the pointer is nil. This ensures that you do not attempt to dereference a nil pointer, which would result in a runtime panic.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>type Node struct {<br>    Value int<br>    Next  *Node<br>}<br><br>func printNodeValue(node *Node) {<br>    if node == nil {<br>        fmt.Println(&quot;Node is nil&quot;)<br>        return<br>    }<br>    fmt.Println(&quot;Node Value:&quot;, node.Value)<br>}<br><br>func main() {<br>    var node *Node<br>    printNodeValue(node) // Output: Node is nil<br><br>    node = &amp;Node{Value: 42}<br>    printNodeValue(node) // Output: Node Value: 42<br>}</pre><p>2. Use Default Values and Initialization:</p><p>Ensure pointers are properly initialized before use. This can be done by providing default values or initializing pointers as part of struct initialization.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>type Config struct {<br>    Name    string<br>    Timeout *int<br>}<br><br>func main() {<br>    defaultTimeout := 30<br>    cfg := Config{Name: &quot;AppConfig&quot;, Timeout: &amp;defaultTimeout}<br><br>    if cfg.Timeout != nil {<br>        fmt.Println(&quot;Timeout:&quot;, *cfg.Timeout) // Output: Timeout: 30<br>    } else {<br>        fmt.Println(&quot;Timeout is not set&quot;)<br>    }<br><br>    // Without initialization<br>    var uninitConfig Config<br>    if uninitConfig.Timeout != nil {<br>        fmt.Println(&quot;Timeout:&quot;, *uninitConfig.Timeout)<br>    } else {<br>        fmt.Println(&quot;Timeout is not set&quot;) // Output: Timeout is not set<br>    }<br>}</pre><p>3. Use Constructor Function:</p><p>Create constructor functions to initialize structs and their pointer fields. This ensures that all fields are properly set up, reducing the risk of nil pointer dereference.</p><pre>package main<br><br>import &quot;fmt&quot;<br><br>type User struct {<br>    Name  string<br>    Email *string<br>}<br><br>func NewUser(name, email string) *User {<br>    return &amp;User{Name: name, Email: &amp;email}<br>}<br><br>func main() {<br>    user := NewUser(&quot;Alice&quot;, &quot;alice@example.com&quot;)<br>    <br>    if user.Email != nil {<br>        fmt.Println(&quot;User Email:&quot;, *user.Email) // Output: User Email: alice@example.com<br>    } else {<br>        fmt.Println(&quot;Email is not set&quot;)<br>    }<br><br>    // Handling nil pointer initialization<br>    var email string<br>    userWithoutEmail := &amp;User{Name: &quot;Bob&quot;}<br>    if userWithoutEmail.Email != nil {<br>        fmt.Println(&quot;User Email:&quot;, *userWithoutEmail.Email)<br>    } else {<br>        fmt.Println(&quot;Email is not set&quot;) // Output: Email is not set<br>    }<br><br>    userWithoutEmail.Email = &amp;email<br>    *userWithoutEmail.Email = &quot;bob@example.com&quot;<br>    fmt.Println(&quot;User Email:&quot;, *userWithoutEmail.Email) // Output: User Email: bob@example.com<br>}</pre><p>These practices help in writing safer Go code by preventing nil pointer dereference errors. For more information try to read <a href="https://go.dev/doc/effective_go">this</a> documentation.</p><p>Although there’s a lot of information here, if you’re new to coding and run into this issue, you can improve as a developer by learning from this. Have no fear of nil pointer dereference; I appreciate you taking the time to read this.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1b0d341fa6b0" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>