Что делает звездочка в «Go» - PullRequest
41 голосов
/ 24 августа 2010

Я веб-разработчик, который хочет расширить свой кругозор, чтобы улучшить программирование в целом. Я сделал немного Java и несколько простых приложений для Android. Сейчас я изучаю языки более низкого уровня, такие как C и Go (которые, я должен сказать, имеют красивый синтаксис и отличные идеи, хотя я, возможно, слишком неопытен, чтобы комментировать).

Так что да, я собираюсь и пытаюсь понять примеры на веб-сайте Go , и я продолжаю сталкиваться со специальным символом звездочки в примере, подобном этому:

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

Кроме того, я только что заметил, что с "& s" это назначение по ссылке (я мог бы использовать здесь разговор по PHP)?

Ответы [ 6 ]

85 голосов
/ 25 августа 2010

*, прикрепленный к типу (*string), указывает на указатель на тип.

*, прикрепленный к переменной в присваивании (*v = ...), указывает на косвенное присвоение.То есть измените значение, на которое указывает переменная.

*, прикрепленный к переменной или выражению (*v), указывает на разыменование указателя.То есть принять значение, на которое указывает переменная.

&, прикрепленный к переменной, или выражение (&v) указывает на ссылку.То есть создайте указатель на значение переменной или на поле.

41 голосов
/ 24 августа 2010

Я предполагаю, что это означает то же самое, что и в C

p is a pointer to a string

Оператор var p *string = &s присваивает адрес объекта s p

Следующая строка *p = "ciao" изменит содержимое s

См. Эту ссылку из FAQ по дизайну языка

Интересно, что арифметика без указателей

Почему нет арифметики с указателями? Безопасность. Без арифметики указателя можно создать язык что никогда не может получить незаконный адрес, который успешно неверно. Компилятор и аппаратные технологии имеют продвинулся до точки, где петля используя индексы массива, можно эффективен как цикл с использованием указателя арифметика. Также отсутствие указателя арифметика может упростить реализация мусора коллектор.

Теперь я хочу начать изучать GO!

22 голосов
/ 08 июля 2014

Go lang Адреса, указатели и типы:

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

Все эти переменные Go имеют адрес.Даже переменные типа «указатель» имеют адреса.Различие состоит в том, что строковые типы содержат строковые значения, типы int содержат целочисленные значения, а типы указателей содержат адреса.

& == оцените адрес или подумайте: «вот мой адрес, чтобы вы знали, где меня найти»

// 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

* == разыменовать указатель или подумать «передать действие по адресу, который является моим значением»

*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)

Перейти Играть здесь: http://play.golang.org/p/u3sPpYLfz7

4 голосов
/ 24 августа 2010

Символ * используется для определения указателя в C и Go. Вместо действительного значения переменная вместо этого имеет адрес для расположения значения. Оператор & используется для получения адреса объекта.

4 голосов
/ 24 августа 2010

Я не знаю Go, но, основываясь на синтаксисе, кажется, что он похож на C - это указатель.Это похоже на ссылку, но более низкий уровень и более мощный.Содержит адрес памяти рассматриваемого элемента.&a получает адрес памяти переменной и *a разыменовывает его, получая значение по адресу памяти.

Кроме того, * в объявлении означает, что это указатель.

Так что да, в PHP это похоже на то, что значение s изменяется, потому что p и &s указывают на один и тот же блок памяти.

2 голосов
/ 01 февраля 2017

Вот как я это вижу.Различные фразы могут помочь кому-то лучше понять это (вы можете скопировать этот код и проверить вывод):

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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...