简体   繁体   中英

What is the meaning of '*' and '&'?

I am doing the http://tour.golang.org/ . Could anyone explain me lines 1,3,5 and 7 this function especially what '*' and '&' do? I mean by mentioning them in a function declaration, what they are supposed/expected to do? A toy example:

1: func intial1(var1 int, var2 int, func1.newfunc[]) *callproperfunction {
2:
3: addition:= make ([] add1, var1)
4: for i:=1;i<var2;i++ {
5:   var2 [i] = *addtother (randomstring(lengthofcurrent))
6:   }
7: return &callproperfunction {var1 int, var2 int, func1.newfunc[], jackpot}
8: }

It seems that they are pointers like what we have in C++. But I cannot connect those concepts to what we have here. In other words, what '*' an '&' do when I use them in function declaration in Go.

I know what reference and dereference mean. What I cannot understand is: how we can use pointer to a function is Go. for example line 1 and 7, what these two lines do? Function named intial1 is declared that returns a pointer? and in line 7, we call it with arguments using return function.

This is possibly one of the most confusing things in Go. There are basically 3 cases you need to understand:

The & Operator

& goes in front of a variable when you want to get that variable's memory address .

The * Operator

* goes in front of a variable that holds a memory address and resolves it (it is therefore the counterpart to the & operator). It goes and gets the thing that the pointer was pointing at, eg *myString .

myString := "Hi"
fmt.Println(*&myString)  // prints "Hi"

or more usefully, something like

myStructPointer = &myStruct
// ...
(*myStructPointer).someAttribute = "New Value"

* in front of a Type

When * is put in front of a type , eg *string , it becomes part of the type declaration, so you can say "this variable holds a pointer to a string". For example:

var str_pointer *string

So the confusing thing is that the * really gets used for 2 separate (albeit related) things. The star can be an operator or part of a type.

Your question doesn't match very well the example given but I'll try to be straightforward.

Let's suppose we have a variable named a which holds the integer 5 and another variable named p which is going to be a pointer. This is where the * and & come into the game.

Printing variables with them can generate different output, so it all depends on the situation and how well you use. The use of * and & can save you lines of code ( that doesn't really matter in small projects ) and make your code more beautiful/readable.

& returns the memory address of the following variable.

* returns the value of the following variable (which should hold the memory address of a variable, unless you want to get weird output and possibly problems because you're accessing your computer's RAM)

var a = 5
var p = &a // p holds variable a's memory address
fmt.Printf("Address of var a: %p\n", p)
fmt.Printf("Value of var a: %v\n", *p)

// Let's change a value (using the initial variable or the pointer)
*p = 3 // using pointer
a = 3 // using initial var

fmt.Printf("Address of var a: %p\n", p)
fmt.Printf("Value of var a: %v\n", *p)

All in all, when using * and & in remember that * is for setting the value of the variable you're pointing to and & is the address of the variable you're pointing to/want to point to.

Hope this answer helps.

Those are pointers like we have in C++.

The differences are:

  • Instead of -> to call a method on a pointer, you always use . , ie pointer.method() .

  • There are no dangling pointers. It is perfectly valid to return a pointer to a local variable. Golang will ensure the lifetime of the object and garbage-collect it when it's no longer needed.

  • Pointers can be created with new() or by creating a object object{} and taking the address of it with & .

  • Golang does not allow pointer-arithmetic (arrays do not decay to pointers) and insecure casting. All downcasts will be checked using the runtime-type of the variable and either panic or return false as second return-value when the instance is of the wrong type, depending on whether you actually take the second return type or not.

This is by far the easiest way to understand all the three cases as explained in the @Everett answer

func zero(x int) {
  x = 0
}
func main() {
  x := 5
  zero(x)
  fmt.Println(x) // x is still 5
}

If you need a variable to be changed inside a function then pass the memory address as a parmeter and use the pointer of this memory address to change the variable permanently.

Observe the use of * in front of int in the example. Here it just represents the variable that is passed as a parameter is the address of type int.

func zero(xPtr *int) {
  *xPtr = 0
}
func main() {
  x := 5
  zero(&x)
  fmt.Println(x) // x is 0
}

& 运算符获取内存地址,其中* 运算符保存特定变量的内存地址。

Simple explanation.. its just like, you want to mutate the original value

func zero(num *int){  // add * to datatype
  *num = 0 // can mutate the original number
}

i := 5
zero(&i) // passing variable with & will allows other function to mutate the current value of variable```

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM