swap function not working in golang - go

Actually i just start to learn golang . In the beginning i think that = and := are same . But then i understand that there is some difference between this two .
I learned swap function in golnag
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
But when i rewrite this function using var this is not working
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
var a, b string
a ="hello"
b="world"
swap(a, b)
fmt.Println(a, b)
}
what is the error in this program ?

Another solution is to use pointers:
package main
import "fmt"
func swap(x, y *string) {
*x, *y = *y, *x
}
func main() {
var a, b string
a ="hello"
b="world"
swap(&a, &b)
fmt.Println(a, b)
}
https://play.golang.org/p/-vxUMlaVmN

The reason is that in second case values returned from swap are ignored. SO nothing is changed.
Try: https://play.golang.org/p/uADEf5X15g
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
var a, b string
a = "hello"
b = "world"
a, b = swap(a, b) //// <----
fmt.Println(a, b)
}

To respond your initial question, you should assign the values returned by swap to a and b like so
a, b = swap(b, a)
Notice that this is simple assignment , without the : attached to the equal
also, instead of a swap function, you could just try inplace reassignment:
a, b = b, a

Variables declaration
var a string - declaration of a variable with null value
a := "spam" - declaration of a variable with a concrete value
func f(a, b string) (string, string) { - declaration of a function with value parameters. It means you have new variables with passed values as arguments each time you call a function.
func f(a, b *string) (*string, *string) { - declaration of a function with pointer arguments. In it's turn it means you have pointers to passed variables each time you call the function.
Also...
a := *string - declaration of a pointer variable.
*a - value of a pointer variable.
&a - pointer of a value
In-place swap
To swap in-place (without returning and reassigning) you should swap values between pointers.
func swap(a, b *string) {
*a, *b = *b, *a
}
p.s.
Take into account that strings is read-only slices of bytes. And slices are reference type it means that an array behind the sub-slices of a common array or slice is the same. It doesn't related to the question but should be considered in such cases.

Related

Golang trying to store the values of pointers

I have a problem and I'm confused about how to solve it.
I have this task:
1. Store the result of the division in the int which a points to.
2. Store the remainder of the division in the int which b points to.
My code is:
package main
import "fmt"
func Function(a *int, b *int) {
*a = *a / *b
*b = *a % *b
}
func main() {
a := 13
b := 2
Function(&a, &b)
fmt.Println(a)
fmt.Println(b)
}
The output should be 6 and 1, however, I don't know how to write the code in the Function func the way it would store the results properly. How do I fix my code? Function should divide the dereferenced value of a by the dereferenced value of b.
The function clobbers the value of *a before the value is used in the second statement. Use this code:
func Function(a *int, b *int) {
*a, *b = *a / *b, *a % *b
}
The expressions on the right hand side of the = are evaluated before assignments to the variables on the left hand side.
Another option is to assign *a / *b to a temporary value:
func Function(a *int, b *int) {
t := *a / *b
*b = *a % *b
*a = t
}

Constructing instances of types with pointer and value receivers [duplicate]

This question already has answers here:
X does not implement Y (... method has a pointer receiver)
(4 answers)
Closed 4 years ago.
Lets take this very small example, having a function that modify value inside the struct:
package learn
type Point struct {
x int
y int
}
func (p *Point) Set(x int, y int) {
p.x = x
p.y = y
}
this works properly, used like this for instance:
package main
import (
"NewPattern/learn"
"fmt"
)
func main() {
p := learn.Point{}
p.Set(5, 6)
fmt.Print(p)
}
it outputs the expected value: {5,6}
Now let's say I don't want the user having a constructor, I can change the code by adding this function:
func NewPoint(x int, y int) Point {
return Point{x, y}
}
then I can use in main like this:
func main() {
p := learn.NewPoint(3, 8)
fmt.Print(p)
p.Set(5, 6)
fmt.Print(p)
}
and it works as expected returning {3 8}{5 6}.
Well now we want to prevent creating point without calling the constructor - not really the case here, but can make sense for complex classes - so we avoid exporting Point and we create an interface instead, so I refactored the code like this: (this is not working!)
package learn
type point struct {
x int
y int
}
type Point interface {
Set(x int, y int)
}
func (p *point) Set(x int, y int) {
p.x = x
p.y = y
}
func NewPoint(x int, y int) Point {
return point{x, y} //error here
}
This says:
cannot use point literal (type point) as type Point in return argument:
point does not implement Point (Set method has pointer receiver)
I can "fix" this by modifying the method in:
func NewPoint(x int, y int) point {
return point{x, y}
}
but this just move the error in main, that is refactored like:
func main() {
var p learn.Point
p = learn.NewPoint(3, 8) //error here!
fmt.Print(p)
p.Set(5, 6)
fmt.Print(p)
}
and the error is:
cannot use learn.NewPoint(3, 8) (type learn.point) as type learn.Point in assignment:
learn.point does not implement learn.Point (Set method has pointer receiver)
by googling I managed to solve in this way:
func NewPoint(x int, y int) *point {
return &point{x, y}
}
but as a result in the main we are obtaining: &{3 8}&{5 6} as a print, ad as well I don't get actually what is happening behind the scenes.
I guess this is somehow related by having things passed and maybe "returned" by value, is this the case? But I don't know how the first examples without interface worked without effort. Can please someone clarify these details that I think are essential to Go understanding.
point and *point (i.e the pointer to point) are two different types. In your code the interface Point is implemented by *point type. You can implement the constructor as:
func NewPoint(x int, y int) Point {
return &point{x, y}
}
The printing will show & befor the points value as the underlying value is a pointer.

Golang Operator Overloading

I understand that golang does not provide operator overloading, as it believe that it is increasing the complexity.
So I want to implement that for structures directly.
package main
import "fmt"
type A struct {
value1 int
value2 int
}
func (a A) AddValue(v A) A {
a.value1 += v.value1
a.value2 += v.value2
return a
}
func main() {
x, z := A{1, 2}, A{1, 2}
y := A{3, 4}
x = x.AddValue(y)
z.value1 += y.value1
z.value2 += y.value2
fmt.Println(x)
fmt.Println(z)
}
https://play.golang.org/p/1U8omyF8-V
From the above code, the AddValue works as I want to. However, my only concern is that it is a pass by value and hence I have to return the newly added value everytime.
Is there any other better method, in order to avoid returning the summed up variable.
Yes, use pointer receiver:
func (a *A) AddValue(v A) {
a.value1 += v.value1
a.value2 += v.value2
}
By using a pointer receiver, the address of a value of type A will be passed, and therefore if you modify the pointed object, you don't have to return it, you will modify the "original" object and not a copy.
You could also simply name it Add(). And you could also make its argument a pointer (for consistency):
func (a *A) Add(v *A) {
a.value1 += v.value1
a.value2 += v.value2
}
And so using it:
x, y := &A{1, 2}, &A{3, 4}
x.Add(y)
fmt.Println(x) // Prints &{4 6}
Notes
Note that even though you now have a pointer receiver, you can still call your Add() method on non-pointer values if they are addressable, so for example the following also works:
a, b := A{1, 2}, A{3, 4}
a.Add(&b)
fmt.Println(a)
a.Add() is a shorthand for (&a).Add(). Try these on the Go Playground.

Avoiding Go copying interface data

This is part of real world code I'm trying to write. The problem is that Go copies the interface sibling so I can't modify the data. However, if I change to using a pointer to an interface then the concept of equality fails. I know I can use DeapEquals, but not in a map.
package main
import (
"fmt"
)
type Q interface {
modify()
}
type P struct {
name string
sibling Q
}
func (x P) modify() {
x.name = "a"
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", a}
B := P{"b", A}
B.sibling.modify()
fmt.Println(B)
fmt.Println(b == B)
}
How do I get Go to let me modify the interface data itself without copying it and modifying the copy?
It seems these are mutually exclusive on a struct:
I need to be able to use maps
I need to be able to modify the interface data with methods
The only way to modify the data without copying it is to use pointers.
I'm a little confused by what you are saying as your example uses a struct and you talk about structs but then you say you need to be able to use maps. Either way, DeepReflect works with both. Here is your example modified to use pointers:
package main
import (
"fmt"
"reflect"
)
type Q interface {
modify()
}
type P struct {
name string
sibling Q
}
func (x *P) modify() {
x.name = "a"
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", &a}
B := P{"b", &A}
B.sibling.modify()
fmt.Println("a:", a)
fmt.Println("A:", A)
fmt.Println("b:", b)
fmt.Println("B:", B)
fmt.Println(b == B)
fmt.Println(reflect.DeepEqual(b, B))
}
Prints:
a: {a <nil>}
A: {a <nil>}
b: {b 0x10436180}
B: {b 0x10436190}
false
true
And you can see this post for doing the same with maps.
You can use value returned from modify()
package main
import (
"fmt"
)
type Q interface {
modify() Q //See here
}
type P struct {
name string
sibling Q
}
func (x P) modify() Q{ //Here
x.name = "a"
return x
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", a}
B := P{"b", A}
B.sibling=B.sibling.modify() //And here
fmt.Println(B)
fmt.Println(b == B)
}
It's verbose a bit, but at least works https://play.golang.org/p/8oM90wriN0

How do I print the pointer value of a Go object? What does the pointer value mean?

I am just playing around with Go and do not yet have a good mental model of when structs are passed by value or by reference.
This may be a very dumb question but I just want to experiment a bit and see if I am still working on the same object or I have made a copy of it (passed it by value).
Is there a way to print the pointer (or internal id if pointer value is changed by gc) of an object?
package main
import ( "runtime" )
type Something struct {
number int
queue chan int
}
func gotest( s *Something, done chan bool ) {
println( "from gotest:")
println( &s )
for num := range s.queue {
println( num )
s.number = num
}
done <- true
}
func main() {
runtime.GOMAXPROCS(4)
s := new(Something)
println(&s)
s.queue = make(chan int)
done := make(chan bool)
go gotest(s, done)
s.queue <- 42
close(s.queue)
<- done
println(&s)
println(s.number)
}
gives on my windows (8g compiled version):
0x4930d4
from gotest:
0x4974d8
42
0x4930d4
42
Why does the pointer value from within the go routine show a different value? The quantity on the original object did get changed so it was working with the same object. Is there a way to see an object id that is persistent?
Go function arguments are passed by value.
First, let's discard the irrelevant parts of your example, so that we can easily see that you are merely passing an argument by value. For example,
package main
import "fmt"
func byval(q *int) {
fmt.Printf("3. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
*q = 4143
fmt.Printf("4. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
q = nil
}
func main() {
i := int(42)
fmt.Printf("1. main -- i %T: &i=%p i=%v\n", i, &i, i)
p := &i
fmt.Printf("2. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
byval(p)
fmt.Printf("5. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
fmt.Printf("6. main -- i %T: &i=%p i=%v\n", i, &i, i)
}
Output:
1. main -- i int: &i=0xf840000040 i=42
2. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=42
3. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=42
4. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=4143
5. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=4143
6. main -- i int: &i=0xf840000040 i=4143
In function main, i is an int variable at memory location (&i) 0xf800000040 with an initial value (i) 42.
In function main, p is a pointer to an int variable at memory location (&p) 0xf8000000f0 with a value (p=&i) 0xf800000040 which points to an int value (*p=i) 42.
In function main, byval(p) is a function call which assigns the value (p=&i) 0xf800000040 of the argument at memory location (&p) 0xf8000000f0 to the function byval parameter q at memory location (&q) 0xf8000000d8. In other words, memory is allocated for the byval parameter q and the value of the main byval argument p is assigned to it; the values of p and q are initially the same, but the variables p and q are distinct.
In function byval, using pointer q (*int), which is a copy of pointer p (*int), integer *q (i) is set to a new int value 4143. At the end before returning. the pointer q is set to nil (zero value), which has no effect on p since q is a copy.
In function main, p is a pointer to an int variable at memory location (&p) 0xf8000000f0 with a value (p=&i) 0xf800000040 which points to a new int value (*p=i) 4143.
In function main, i is an int variable at memory location (&i) 0xf800000040 with a final value (i) 4143.
In your example, the function main variable s used as an argument to the function gotest call is not the same as the function gotest parameter s. They have the same name, but are different variables with different scopes and memory locations. The function parameter s hides the function call argument s. That's why in my example, I named the argument and parameter variables p and q respectively to emphasize the difference.
In your example, (&s) 0x4930d4 is the address of the memory location for the variable s in function main that is used as an argument to the function call gotest(s, done), and 0x4974d8 is the address of the memory location for the function gotest parameter s. If you set parameter s = nil at the end of function gotest, it has no effect on variable s in main; s in main and s in gotest are distinct memory locations. In terms of types, &s is **Something, s is *Something, and *s is Something. &s is a pointer to (address of memory location) s, which is a pointer to (address of memory location) an anonymous variable of type Something. In terms of values, main.&s != gotest.&s, main.s == gotest.s, main.*s == gotest.*s, and main.s.number == gotest.s.number.
You should take mkb's sage advice and stop using println(&s). Use the fmt package, for example,
fmt.Printf("%v %p %v\n", &s, s, *s)
Pointers have the same value when they point to the same memory location; pointers have different values when they point to different memory locations.
In Go, arguments are passed by value.
package main
import "fmt"
type SomeStruct struct {
e int
}
// struct passed by value
func v(v SomeStruct) {
fmt.Printf("v: %p %v\n", &v, v)
v.e = 2
fmt.Printf("v: %p %v\n", &v, v)
}
// pointer to struct passed by value
func p(p *SomeStruct) {
fmt.Printf("p: %p %v\n", p, *p)
p.e = 2
fmt.Printf("p: %p %v\n", p, *p)
}
func main() {
var s SomeStruct
s.e = 1
fmt.Printf("s: %p %v\n", &s, s)
v(s)
fmt.Printf("s: %p %v\n", &s, s)
p(&s)
fmt.Printf("s: %p %v\n", &s, s)
}
Output:
s: 0xf800000040 {1}
v: 0xf8000000e0 {1}
v: 0xf8000000e0 {2}
s: 0xf800000040 {1}
p: 0xf800000040 {1}
p: 0xf800000040 {2}
s: 0xf800000040 {2}
type sometype struct { }
a := sometype {}
b := int(2)
println("Ptr to a", &a)
println("Ptr to b", &b)
How do I print the pointer value of a Go object?
package main
import (
"fmt"
)
func main() {
a := 42
fmt.Println(&a)
}
results in:
0x1040a124
What does the pointer value mean?
According to Wikipedia:
A pointer references a location in memory
package main
import "fmt"
func zeroval(ival int) {
ival = 0
}
func zeroptr(iptr *int) {
*iptr = 0
}
func main() {
i := 1
fmt.Println("initial:", i)
zeroval(i)
fmt.Println("zeroval:", i)
//The &i syntax gives the memory address of i, i.e. a pointer to i.
zeroptr(&i)
fmt.Println("zeroptr:", i)
//Pointers can be printed too.
fmt.Println("pointer:", &i)
}
OUTPUT:
$ go run pointers.go
initial: 1
zeroval: 1
zeroptr: 0
pointer: 0x42131100

Resources