Related
Why if I print bs, before calling Read(), it prints nothing, but after the call file.Read(bs), it shows the inside of test.txt file. Unless bs is only argument, how Read() can Change it?
package main
import (
"os"
"fmt"
)
func main() {
file , err := os.Open("test.txt")
if err == nil {
} else {
}
stat , _ := file.Stat()
bs := make([]byte, stat.Size())
fmt.Println(string(bs))
bsf ,err := file.Read(bs)
if err != nil{
fmt.Println(err)
fmt.Println(bsf)
}
fmt.Println(string(bs))
}
Output:
(Line1)
(Line2)hi, This is Example text in test.txt file.
Unless bs is only argument, how Read() can Change it?
It seems that you may be missing basic knowledge about programming languages in general. There are different kind of "values". There are pointers (or references) and there are the "usual values".
For example:
package main
import (
"fmt"
)
func changeIt(p *int) {
*p = 9
}
func main() {
a := 1
fmt.Println(a)
changeIt(&a)
fmt.Println(a)
}
It'll print 1 9 not 1 1. *int is not an integer, but a pointer to an integer. A pointer is a value that points (references) another value. If you have a value of type pointer you get the actual value that the pointer points to by using * (which is called dereferencing):
func main() {
a := 1
b := &a
fmt.Println(b, *b)
}
b is a pointer (of type *int) that points to a. The println will print the location of a followed by the value of a which is usually something like uhm 0x10414020 1. We can also modify the value a pointer points to by using *p = ...:
func main() {
a := 1
b := &a
*b = 9
fmt.Println(b, *b, a)
}
which will print 0x10414020 9 9.
Now, []byte is a slice... slices are like pointers. When you do
func changeIt(buf []byte) {
buf[0] = 10
}
func main() {
data := []byte{1,2,3}
changeIt(data)
fmt.Println(data)
}
You're not actually passing the values [1 2 3] to changeIt but a pointer to those values. Thus here the println will show [10 2 3]. Compare this to:
func changeIt(buf [3]byte) {
buf[0] = 10
}
func main() {
data := [3]byte{1,2,3}
changeIt(data)
fmt.Println(data)
}
Which will print [1 2 3] and it will pass the values [1 2 3] and not a pointer so changeIt essentially works on a copy and the buf[0] = 10 has no effect. Remember: [n]T is an array, []T is a slice. [n]T is a "raw value" and []T is a "pointer value".
I defined my Int type as int.
I want to convert a slice of Int to a slice of int, but got a compile error:
cannot convert c (type []Int) to type []int
How can I fix this?
package main
import (
"fmt"
)
type Int int
func main() {
var c = []Int{}
var x = []int( c )
fmt.Println(len(x))
}
Your Int type is not an alias of int, it's a new type with int being its underlying type. This type of conversion is not supported / allowed by the language spec. More specifically, converting a slice type to another where the element type is different is not allowed.
The safe way
If you only need an []int "view" of the []Int, the safe way to "convert" would be to create a copy of the []Int slice but with a type of []int, and use a for range loop and convert each individual element from Int to int type:
var c = []Int{1, 2}
x := make([]int, len(c))
for i, v := range c {
x[i] = int(v)
}
fmt.Println(x)
Output (try it on the Go Playground):
[1 2]
The unsafe way
There is also an "unsafe" way:
var c = []Int{1, 2}
var x []int = *(*[]int)(unsafe.Pointer(&c))
fmt.Println(x)
Output is the same. Try this one on the Go Playground.
What happens here is that the address of c (which is &c) is converted to unsafe.Pointer (all pointers can be converted to this), which then is converted to *[]int (unsafe.Pointer can be converted to any pointer type), and then this pointer is dereferenced which gives a value of type []int. In this case it is safe because the memory layout of []Int and []int is identical (because Int has int as its underlying type), but in general, use of package unsafe should be avoided whenever possible.
If Int would be a "true" alias
Note that if Int would be a "true" alias to int, the conversion would not even be needed:
var c = []Int{1, 2}
var x []int = c
fmt.Println(x)
Output is the same as above (try it on the Go Playground). The reason why this works is because writing []Int is identical to writing []int, they are the same type, so you don't even need a conversion here.
By using a slice type
Also note that if you would create a new type with []int as its underlying type, you could use type conversion:
type IntSlice = []int
func main() {
var c = IntSlice{1, 2}
var x []int = []int(c)
fmt.Println(x)
}
Output is again the same. Try this one on the Go Playground.
The problem is that you are not creating Int as an alias, doing
type Int int
Will create Int as a new type that can't interoperate with int.
The proper way to create Int as an alias is
type Int = int
With this change your program is ok.
Technically, type Int int does not define an alias, but a completely new type. Even though Int and int now have identical underlying types and can be converted to each other, that does not apply to slices. More about allowed conversions is in the spec.
Actually, a slice a simply points to an underlying array of the designated type (in this case the types are different, Int and int). So unless your underlying type is the same a conversion won't work. Just to illustrate this something like this would work though:
package main
import (
"fmt"
)
type Int int
type IntSl []int
func main() {
var c = IntSl{2, 3, 4}
var x []int
x = []int(c)
var a Int
var b int
a = 1
b = int(a)
fmt.Println(len(x), a, b, c)
}
Playground : https://play.golang.org/p/ROOX1XoXg1j
As #icza points out there's the unsafe way & of course you can always do the conversion looping over each of the elements which could be expensive.
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.
Considering the following example methods, each of which returns three integers:
func a() (int, int, int) {...}
func b() (int, int, int) {...}
I want to know if the return values of these methods are the same, something like this:
equal := a() == b()
However, this doesn't compile because the compiler is expecting a single value:
my_file.go:14: multiple-value a() in single-value context
my_file.go:14: multiple-value b() in single-value context
My current work around is to create a custom type with the same signature as the methods, and then create a third function to do the checking:
type multiReturnFunc func() (int, int, int)
func a() (int, int, int) {...}
func b() (int, int, int) {...}
func checkMultiReturns(a, b multiReturnFunc) bool {
a1, a2, a3 := a()
b1, b2, b3 := b()
return a1 == b1 && a2 == b2 && a3 == b3
}
...
equal := checkMultiReturns(a, b)
But I would like to have a more general solution.
With structs
You can slightly improve it by storing the result in values of a struct which are comparable:
type Result struct {
a, b, c int
}
And using it:
p, q := Result{}, Result{}
p.a, p.b, p.c = a()
q.a, q.b, q.c = b()
fmt.Println(p == q)
With arrays
Or you can use arrays (arrays are also comparable unlike slices), although this won't be shorter, but you don't need a new type for this:
x, y := [3]int{}, [3]int{}
x[0], x[1], x[2] = a()
y[0], y[1], y[2] = b()
fmt.Println(x == y)
General solution (using reflect)
A general solution may be constructed using the reflect package. This basically calls both functions, and compares all the result values. Error checks omitted!
func check(v1, v2 reflect.Value) bool {
r1 := v1.Call(nil)
r2 := v2.Call(nil)
if len(r1) != len(r2) {
return false
}
for i, a := range r1 {
if a.Interface() != r2[i].Interface() {
return false
}
}
return true
}
And using it:
fmt.Println(check(reflect.ValueOf(a), reflect.ValueOf(b)))
Try these on the Go Playground.
This might not be exactly what you want, but if instead of returning three unnamed ints you return structs, you can compare them directly. E.g.
type XYZ struct{ X, Y, Z int }
func f() XYZ { return XYZ{1, 2, 3} }
func g() XYZ { return XYZ{1, 2, 3} }
func main() {
fmt.Println(f() == g())
// Output:
// true
}
Playground: http://play.golang.org/p/zFXPqPjTtZ.
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