/* * A couple of looks at the lifespan of variables * @author gtowell * created: July 20, 2021 */ package main import "fmt" // A struuct with two members type AAA struct { BB int CC float64 } // the variable q is a global instance of the AAA type var q AAA func main() { qq := AAA{BB: 5, CC: 128.5} // make a new local variable q = AAA{BB: 6, CC: 256.8} // make an instance of the struct and store it in q fmt.Printf("qq=%v\nq=%v\n\n", qq, q) r := stackQ(17, 1024.2) fmt.Printf("AddR=%p\n", &r) fmt.Printf("r=%v\nq=%v\n\n", r, q) s := stackQ(42, 2048.1) fmt.Printf("AddS=%p\n", &s) // this address is different from the one in the function. In return by value a new thing is created during the return. You can see that this MUST be the case because of the := in line 26 fmt.Printf("s=%v\nr=%v\nq=%v\n\n", s, r, q) sh := make([]int, 10) sh[0] = 5 fmt.Printf("sh=%v\n", sh) func2(sh) fmt.Printf("sh=%v\n", sh) func3(1, 2) func3(1, 2, 3, 4, 5, 6) } // Make an instance of the struct AAA and return it. // Note that the thing returned in not actually the thing made, // but a new copy of it. func stackQ(bb int, cc float64) AAA { sq := AAA{BB: bb, CC: cc} fmt.Printf("sq=%v\nq=%p\n", sq, &sq) return sq } // slices are passed by reference, so simple changes to existng locations in a slice do not change the pointer. func func2(slic []int) { slic[1] = 4 } // Note that iii gets made in this func. It may get changed by every append -- so need to recatch iii after each append. func func3(a ...int) { // allocated from heap -- probably. Go does not actually specify iii := make([]int, 2) // make a slice with initial room for 2 items jjj := iii fmt.Printf("SLICES %p %p\n", iii, jjj) for idx, aa := range a { if idx >= len(iii) { // what happens to old iii if new iii is not the same iii = append(iii, aa) } else { iii[idx] = aa } } fmt.Printf("iii=%v\n", iii) fmt.Printf("jjj==iii %t\n", cap(jjj) == cap(iii)) }