星号在“开始”中有什么作用

星号在“开始”中有什么作用

问题描述:

I'm a web developer looking to expand my horizons in order to get better at programming as a whole. I've done a bit Java and some simple Android applications. I'm now looking into lower level languages like C and Go (which I must say has some beautiful syntax and great ideas thus far, though I'm maybe too inexperienced to comment).

So yeah I've been going though and trying to understand the examples on the Go website and I keep coming across a special asterisk character in example like this:

s := "hello"
if s[1] != 'e' {
    os.Exit(1)
}
s = "good bye"
var p *string = &s
*p = "ciao"

Also, I just noticed, whats with the "&s" is it assignment by reference (I might be using PHP talk here)?

Im guessing it means the same as in C

p is a pointer to a string

The statement var p *string = &s would assign the address of the s object to p

Next line *p = "ciao" would change the contents of s

See this link from the Language Design FAQ

Interestingly, no pointer arithmetic

Why is there no pointer arithmetic? Safety. Without pointer arithmetic it's possible to create a language that can never derive an illegal address that succeeds incorrectly. Compiler and hardware technology have advanced to the point where a loop using array indices can be as efficient as a loop using pointer arithmetic. Also, the lack of pointer arithmetic can simplify the implementation of the garbage collector.

Now I want to start learning GO!

I don't know Go, but based on the syntax, it seems that its similar to C - That is a pointer. Its similar to a reference, but lower level and more powerful. It contains the memory address of the item in question. &a gets the memory address of a variable and *a dereferences it, getting the value at the memory address.

Also, the * in the declaration means that it is a pointer.

So yes, its like in PHP in that the value of s is changed because p and &s point to the same block of memory.

The * character is used to define a pointer in both C and Go. Instead of a real value the variable instead has an address to the location of a value. The & operator is used to take the address of an object.

* attached to a type (*string) indicates a pointer to the type.

* attached to a variable in an assignment (*v = ...) indicates an indirect assignment. That is, change the value pointed at by the variable.

* attached to a variable or expression (*v) indicates a pointer dereference. That is, take the value the variable is pointing at.

& attached to a variable or expression (&v) indicates a reference. That is, create a pointer to the value of the variable or to the field.

Go lang Addresses, Pointers and Types:

s := "hello"      // type string
t := "bye"        // type string
u := 44           // type int
v := [2]int{1, 2} // type array 

All these Go variables have an address. Even variables of type "pointer" have addresses. The distinction is string types hold string values, int types hold integer values, and pointer types hold addresses.

& == evaluate to address, or think "here's my address so you know where to find me"

// make p type pointer (to string only) and assign value to address of s
var p *string = &s // type *string
// or
q := &s // shorthand, same deal

* == dereference pointer, or think "pass action on to the address which is my value"

*p = "ciao"   // change s, not p, the value of p remains the address of s

// j := *s    // error, s is not a pointer type, no address to redirect action to
// p = "ciao" // error, can't change to type string

p = &t        // change p, now points to address of t
//p = &u      // error, can't change to type *int

// make r type pointer (to pointer [to string]) and assign value to address of p
var r **string = &p // shorthand: r := &p

w := (  r == &p) // (  r evaluates to address of p) w = true
w =  ( *r == p ) // ( *r evaluates to value of p [address of t]) w = true
w =  (**r == t ) // (**r evaluates to value of t) w = true

// make n type pointer (to string) and assign value to address of t (deref'd p)
n := &*p
o := *&t // meaningless flip-flop, same as: o := t

// point y to array v
y := &v
z := (*y)[0] // dereference y, get first value of element, assign to z (z == 1)

Go Play here: http://play.golang.org/p/u3sPpYLfz7

That's how I see it. Different phrasing might help someone to understand it better (you can copy paste that code and examine the output):

package main

import (
    "fmt"
)

func main() {
    // declare a variable of type "int" with the default value "0"
    var y int

    // print the value of y "0"
    fmt.Println(y)

    // print the address of y, something like "0xc42008c0a0"
    fmt.Println(&y)

    // declare a variable of type "int pointer"
    // x may only hold addresses to variables of type "int"
    var x *int

    // y may not simply be assigned to x, like "x = y", because that 
    // would raise an error, since x is of type "int pointer", 
    // but y is of type "int"

    // assign address of y "0xc42008c0a0" as value to x
    x = &y

    // print the value of x "0xc42008c0a0" which is also the address of y
    fmt.Println(x)

    // print the address of x, something like "0xc420030028" 
    // (x and y have different addresses, obviously)
    fmt.Println(&x)

    // x is of type "int pointer" and holds an address to a variable of 
    // type "int" that holds the value "0", something like x -> y -> 0;
    // print the value of y "0" via x (dereference)
    fmt.Println(*x)

    // change the value of y via x
    *x = 1; /* same as */ y = 1

    // print value of y "1"
    fmt.Println(y); /* same as */ fmt.Println(*x)
}