Home > Back-end >  Golang: "missing return at end of function" when sending queries for item in text file
Golang: "missing return at end of function" when sending queries for item in text file

Time:12-08

I have this code where I send get requests per line in a text file. However, when I'm trying to run the code I get an error saying "missing return at end of function". I know that this is most likely due to the fact that I'm returning it before the final bracket, but I need the code within that bracket as It's defining the lines, the requests and the body content.

My code:

// Routine
func main() {
    rep := 1000
    results := make(chan string)

    for i := 0; i < rep; i   {
        go func(num int) {
            results <- request(num)
        }(i)
    }

    for i := 0; i < rep; i   {
        fmt.Println(<-results)
    }
}

func request(num int) string {
    // For name in names.txt
    wordlist, err := readLines("assets/names.txt")
    if err != nil {
        log.Fatalf("readLines: %s", err)
    }
    for _, line := range wordlist {
        // Send request
        response, err := http.Get("https://accounts.com/"   line   "/userId")
        if err != nil {
            fmt.Printf("%s", err)
        }

        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
          fmt.Printf("%s", err)
          os.Exit(1)
        }
        fmt.Printf("%s\n", string(contents))
        return string(contents) 
    }
}

CodePudding user response:

As per the Go Programming Language Specification

If the function's signature declares result parameters, the function body's statement list must end in a terminating statement.

To assist in explaining the issue we can simplify your code to:

package main

import "fmt"

func main() {
    fmt.Println(request([]string{"foo"}))
}

func request(wordlist []string) string {
    for _, line := range wordlist {
        // Do something
        return line
    }
}

The error can be fixed by adding a return after the loop:

package main

import "fmt"

func main() {
    fmt.Println(request([]string{"foo"}))
}

func request(wordlist []string) string {
    for _, line := range wordlist {
        // Do something
        return line
    }
    return ""
}

The reason that the extra return is needed is because the function could be passed an empty slice. In that case the code within the for is never executed meaning that there is no terminating statement (note that you could replace the return with a panic). The same applies in your code if readLines returns an empty slice.

I think it's worth noting that using a loop here does not make a lot of sense because you appear to only be interested in the first value. You could achieve the same result with something like:

package main

import "fmt"

func main() {
    fmt.Println(request([]string{"foo", "boo"}))
    fmt.Println(request(nil))
}

func request(wordlist []string) string {
    if len(wordlist) == 0 {
        return "No Data"
    }

    line := wordlist[0]
    // do something...
    return line
}

I suspect that you actually want to process all of the lines but unfortunately your question does not provide sufficient context to assist further.

CodePudding user response:

Your function wants to lookup a text. So in that loop:
step out of the loop after you found it,
then return the value. (I minimised it a bit)

    result := ""
    for _, line := range wordlist {
        if found {
            result = yourAnswer
            break
        }
    }
    return result

}
  • Related