Go lang empty struct confusing feature [duplicate] - go

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?

Related

Printing variables changes the previous code results [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 months ago.
I have the following code:
package main
import "fmt"
type MyStruct struct {
}
func main() {
a := &MyStruct{}
b := &MyStruct{}
fmt.Println(a == b)
fmt.Println(*a == *b)
}
Which as expected outputs
false
true
But, if I add two Print statements at the end like this:
package main
import "fmt"
type MyStruct struct {
}
func main() {
a := &MyStruct{}
b := &MyStruct{}
fmt.Println(a == b)
fmt.Println(*a == *b)
fmt.Println(&a)
fmt.Println(&b)
}
The output becomes something I did not expect:
true
true
0xc0000ae018
0xc0000ae020
Why does it become true in the first case?
From the Go language specification:
Pointers to distinct zero-size variables may or may not be equal.
MyStruct is struct{}, which is a zero-size type. Hence, a == b may be true or false.

Name of current function [duplicate]

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

Parameter that's a list of interface{} [duplicate]

This question already has an answer here:
Passing interface{} or []interface{} in Golang
(1 answer)
Closed 4 years ago.
I'm trying to create a function that prints out the len of a list passed into it, regardless of the type of the list. My naive way of doing this was:
func printLength(lis []interface{}) {
fmt.Printf("Length: %d", len(lis))
}
However, when trying to use it via
func main() {
strs := []string{"Hello,", "World!"}
printLength(strs)
}
It complains saying
cannot use strs (type []string) as type []interface {} in argument to printLength
But, a string can be used as a interface{}, so why can't a []string be used as a []interface{}?
You can use reflect package - playground
import (
"fmt"
"reflect"
)
func printLength(lis interface{}) {
fmt.Printf("Length: %d", reflect.ValueOf(lis).Len())
}

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?

How can I cast from []interface{} to []int? [duplicate]

This question already has answers here:
Type converting slices of interfaces
(9 answers)
Closed 7 years ago.
I would like to get non duplicated []int.
I'm using set, but I don't know how to get []int from set.
How can I do that?
package main
import (
"fmt"
"math/rand"
"time"
"github.com/deckarep/golang-set"
)
func pickup(max int, num int) []int {
set := mapset.NewSet()
rand.Seed(time.Now().UnixNano())
for set.Cardinality() < num {
n := rand.Intn(max)
set.Add(n)
}
selected := set.ToSlice()
// Do I need to cast from []interface{} to []int around here?
// selected.([]int) is error.
return selected
}
func main() {
results := pickup(100, 10)
fmt.Println(results)
// some processing using []int...
}
There is no automatic way to do that. You need to create an int slice and copy into it:
selected := set.ToSlice()
// create a secondary slice of ints, same length as selected
ret := make([]int, len(selected))
// copy one by one
for i, x := range selected {
ret[i] = x.(int) //provided it's indeed int. you can add a check here
}
return ret

Resources