Name of current function [duplicate] - go

This question already has answers here:
How to get the current function name
(4 answers)
Closed 4 years ago.
Is there a way to include the name of the current function I am in? I'd like to include it in my debug logs rather than hard coding the func name which is a pain after a while.
Thanks.

You can do this using runtime.Callers
package main
import (
"fmt"
"runtime"
)
func printFuncName() {
fpcs := make([]uintptr, 1)
// Skip 2 levels to get the caller
n := runtime.Callers(2, fpcs)
if n == 0 {
fmt.Println("MSG: NO CALLER")
}
caller := runtime.FuncForPC(fpcs[0] - 1)
if caller == nil {
fmt.Println("MSG CALLER WAS NIL")
}
// Print the name of the function
fmt.Println(caller.Name())
}
func foo() {
printFuncName()
}
func main() {
foo()
}
Outputs (package.function)
main.foo

Related

rand.Intn generating same random sequences multiple time [duplicate]

This question already has answers here:
Go rand.Intn same number/value
(3 answers)
Closed 2 years ago.
I am trying to write a function that generates a random sequence with an alphanumeric character, Unfortunately, the function returns the same random sequence when calling multiple times.
I even tried by seeding the rand with time.Now().UTC().UnixNano(), even though getting the same values again and again
Main Package:
package main
import (
"fmt"
"time"
"userpkg/random"
)
func main() {
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
}
Random Package
package random
func RandomHash(length int8) string {
rand.Seed(time.Now().UTC().UnixNano())
pool := []byte(`0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`)
/* allocate a new slice array to store the hash */
buf := make([]byte, length)
for i := int8(0); i < length; i++ {
buf[i] = pool[rand.Intn(len(pool))]
}
rand.Shuffle(len(buf), func(i, j int) {
buf[i], buf[j] = buf[j], buf[i]
})
str := string(buf)
return str
}
Output :
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Please guide me on how to solve this issue, Thanks
You need to seed the math/rand package once only. If you call the RandomHash() function "very fast", you will seed it to the same value, so it will use the same random values, resulting in the same result! On top of this, on the Go Playground the time is deterministic (it doesn't elapse unless e.g. time.Sleep() is called!).
Move the seeding outside of RandomHash(), e.g. to a package init() function:
func init() {
rand.Seed(time.Now().UnixNano())
}
func RandomHash(length int8) string {
// ...
}
Then each return value of RandomHash() will (likely) be different, e.g. (try it on the Go Playground):
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
8XhJlp6EAXqqbEcPLQL83pw8wUiJRl7D
HGWpHldhGWpzl2KY10ua15T04N1eoPp7
huRNzf4eD7IIuqYNjoMZB5z6r0RFRB64
Also see related question:
How to generate a random string of a fixed length in Go?

Go lang empty struct confusing feature [duplicate]

This question already has answers here:
why struct arrays comparing has different result
(1 answer)
Addresses of slices of empty structs
(2 answers)
Closed 2 years ago.
Here is my code:
package main
import (
"fmt"
)
type A struct{}
func main() {
var ad, bd A
res1 := &ad == &bd
res2 := ad == bd
fmt.Println(res1, res2)// true true
fmt.Printf("%p, %p\n", &ad, &bd) // 0x57bb60, 0x57bb60
}
Now if I comment the last line of main function like this:
package main
import (
"fmt"
)
type A struct{}
func main() {
var ad, bd A
res1 := &ad == &bd
res2 := ad == bd
fmt.Println(res1, res2) // false true
//fmt.Printf("%p, %p\n", &ad, &bd)
}
The program prints false true!
How can the last line influence the output?
Is there any special feature with the empty struct?
Or this problem is caused by the compiler?

Undefined variable golang [duplicate]

This question already has answers here:
Variable scope inside if statements
(2 answers)
Closed 4 years ago.
Can someone tell me why num is undefined :: Here is go playground link also you can check this code here:
https://play.golang.org/p/zR9tuVTJmx-
package main
import "fmt"
func main() {
if 7%2 == 0 {
num := "first"
} else {
num := "second"
}
fmt.Println(num)
}
That's something related to lexical scoping, look over here for an introduction
Basically any variable within {}curly braces is considered as new variable, within that block.
so In the above program you have created two new variables.
Block is something like enclosing a around a variable.
If you are outside a block, you cannot see it. you need to be inside the block in order to see it.
package main
import "fmt"
func main() {
if 7%2 == 0 {
// you are declaring a new variable,
num := "first"
//this variable is not visible beyond this point
} else {
//you are declaring a new variable,
num := "second"
//this variable is not visible beyond this point
}
// you are trying to access a variable, which is declared in someother block,
// which is not valid, so undefined.
fmt.Println(num)
}
What you are looking for is this:
package main
import "fmt"
func main() {
num := ""
if 7%2 == 0 {
//num is accessible in any other blocks below it
num = "first"
} else {
num = "second"
}
//num is accessible here as well, because we are within the main block
fmt.Println(num)
}

How can I insert a new element to slice when the method is self defined? [duplicate]

This question already has answers here:
Golang Operator Overloading
(1 answer)
Why can't I append to a slice that's the property of a struct in golang?
(1 answer)
Closed 5 years ago.
When I tried to add a new method to an aliased type, append method not works.
package main
import (
"fmt"
)
type Strings []string
func (ss Strings) Add(s string) {
ss = append(ss, s)
}
func main() {
ss := make(Strings, 0)
ss = append(ss, "haha", "h3h3")
fmt.Println(ss) // got [haha h3h3]
ss.Add("lala")
fmt.Println(ss) // also got [haha h3h3], and why ?
}
Why doesn't "lala" get appended to ss?

Is there a way to generically represent a group of similar functions? [duplicate]

This question already has answers here:
Type func with interface parameter incompatible error
(1 answer)
Func with interface argument not equals to func with string argument. Why?
(1 answer)
Go function types that return structs being used with interfaces
(2 answers)
Passing an arbitrary function as a parameter in Go
(4 answers)
How to convert from `func() *int` to `func() interface{}`? [duplicate]
(1 answer)
Closed 8 months ago.
package main
import "fmt"
type Pet interface {
Bark()
}
type Dog int
func (d Dog) Bark() {
fmt.Println("W! W! W!")
}
type Cat int
func (c Cat) Bark() {
fmt.Println("M! M! M!")
}
type AdoptFunc func(pet Pet)
func adoptDog(dog Dog) {
fmt.Println("You live in my house from now on!")
}
func adoptCat(cat Cat) {
fmt.Println("You live in my house from now on!")
}
func main() {
var adoptFuncs map[string]AdoptFunc
adoptFuncs["dog"] = adoptDog // cannot use adoptDog (type func(Dog)) as type AdoptFunc in assignment
adoptFuncs["cat"] = adoptCat // the same as above
}
As the code above, is there a way to use a map or array to collect a bunch of similar functions adoptXxx? If not, what is right pattern to use for this situation?
To use the map as a function collection you'll have to change the signature of your functions to match. func(Pet) is not the same type as func(Dog).
You can re-write AdoptXXX functions to take in Pet and do a type select to ensure correct pet is being input:
func adoptDog(pet Pet) {
if _, ok := pet.(Dog); !ok {
// process incorrect pet type
}
fmt.Println("You live in my house from now on!")
}

Resources