从嵌套块返回,范围问题

Basic concept

I'm learning Go and I can't understand how to return data from an inner block of a function.

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
    if isTrue("asasa") {
        fmt.Println("isTrue is true")
    }
}

func isTrue(s string) bool {
    if s == "asasa" {
        fmt.Println("it matches")
        return true
    }
}

https://play.golang.org/p/x6l29CNdg-o

How should I return a condition met inside a nested (even multiple time nested) block?

Real case scenario

func isUnique(h, c, L float64) bool {

    for i, color := range usuedColors {
        if color[0] == h && color[1] == c && color[2] == L {
            fmt.Println("This color already exist!")
            return false
        } else {
            return true
        }
    }
}

I receive a triple of values h, c, L and I want to check if it is unique against a 2D slice where I've previously stored other triples. I cycle through all the triple and if a match exist I want isUnique to return as false, else true.

Check for value returned from the function, assign it to variable and use it in main when checking for the condition as below: package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
    if ok := isTrue("asasa"); ok {
        fmt.Println("isTrue is true")
    }
}

func isTrue(s string) bool {
    boolean := false
    for i := 0; i < 5; i++ {
        if s == "asasa" {
            fmt.Println("it matches")
            boolean = true
        }
    }
    return boolean
}

In Golang Effective Go for If control statement it is described:

Since if and switch accept an initialization statement, it's common to see one used to set up a local variable.

if err := file.Chmod(0664); err != nil {
    log.Print(err)
    return err
}

In the Go libraries, you'll find that when an if statement doesn't flow into the next statement—that is, the body ends in break, continue, goto, or return—the unnecessary else is omitted.

f, err := os.Open(name)
if err != nil {
    return err
}
codeUsing(f)

It is also used in maps to check if value exists or not on basis of keys. Check this link for Effective Go on maps to know more about comma ok syntax.

Working code updated on Go playground

Fix your compile error: : missing return at end of function. For example,

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
    if isTrue("asasa") {
        fmt.Println("isTrue is true")
    }
}

func isTrue(s string) bool {
    if s == "asasa" {
        fmt.Println("it matches")
        return true
    }
    return false
}

Playground: https://play.golang.org/p/AYj7tcXd49k

Output:

Hello, playground
it matches
isTrue is true

The Go Programming Language Specification

Return statements

A "return" statement in a function F terminates the execution of F.


For the real case that you just added:

func isUnique(h, c, L float64) bool {
    for i, color := range usedColors {
        if color[0] == h && color[1] == c && color[2] == L {
            fmt.Println("This color already exist!")
            return false
        }
    }
    return true
}

If I understood your problem correctly, this is a general logic problem rather than a golang problem or returning from a block. The problem with your code:

func isUnique(h, c, L float64) bool {
    for i, color := range usuedColors {
        if color[0] == h && color[1] == c && color[2] == L {
            fmt.Println("This color already exist!")
            return false
        } else {
            return true
        }
    }
}

Is that it only checks the very first color, not all of them. What you really want is to first check if any of them match

    for i, color := range usuedColors {
        if color[0] == h && color[1] == c && color[2] == L {
            fmt.Println("This color already exist!")
            return false
        }
    }

And only if none of them matched, return true.

func isUnique(h, c, L float64) bool {
    for i, color := range usuedColors {
        if color[0] == h && color[1] == c && color[2] == L {
            fmt.Println("This color already exist!")
            return false
        }
    }
    return true
}