English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Указатель в языке программирования Go — это переменная, которая хранит адрес другой переменной. Указатели в Golang также называются особыми переменными.ПеременнаяИспользуется для хранения данных в определенном положении памяти системы. Всегда можно найти адрес памяти в шестнадцатеричном формате (начинается с 0x, например, 0xFFAAF и т.д.).
Функция указателя?
Чтобы понять этот указатель, сначала我们必须 понять концепцию переменной. Переменная — это имя, присвоенное хранящемуся в памяти фактическому положению данных. Для доступа к хранящимся данным нам нужно адрес этого конкретного места хранения. Запомнить все адреса памяти (в шестнадцатеричном формате) является затратным мероприятием, поэтому мы используем переменные для хранения данных и можем доступа к переменным, используя только имена переменных.
Golang также позволяет использовать литеральные выражения для сохранения шестнадцатеричных чисел в переменных, то есть, от0xНачальные числа — это шестнадцатеричные числа.
Пример:В следующем примере мы будем хранить шестнадцатеричные числа в переменных. Но вы можете видеть, что тип значения —intи сохраняется как десятичное, или, можно сказатьintДесятичное значение типа хранится. Однако, основная идея этого примера заключается в том, что мы храним шестнадцатеричные значения (их можно рассматривать как адреса памяти), но это не указатель, так как он не указывает на любое другое положение памяти переменной. Это просто пользовательски определенная переменная. Поэтому нам нужно использовать указатели.
//Хранение шестнадцатеричных значений package main import "fmt" func main() { //Хранение шестнадцатеричных значений //Значения переменных x := 0xFF y := 0x9C // Показывать значения fmt.Printf("Тип переменной x равно %T\n", x) fmt.Printf("Шестнадцатеричное значение x равно %X\n", x) fmt.Printf("Десятичное значение x равно %v\n", x) fmt.Printf("Тип переменной y равно %T\n", y) fmt.Printf("Шестнадцатеричное значение y равно %X\n", y) fmt.Printf("Десятичное значение y равно %v\n", y) }
Вывод:
Тип переменной x — int Шестнадцатеричное значение x равно FF Десятичное значение x равно 255 Тип переменной y — int Шестнадцатеричное значение y равно 9C Десятичное значение y равно 156
Указатель — это особый вид переменной, который не только хранит адрес других переменных, но и указывает на положение в памяти, предоставляя способ поиска значения, хранящегося в этом положении памяти. Он обычно называется особым типом переменной, так как он почти как переменная, но с*(оператор разымеения).
Прежде чем начать, мы рассмотрим два важных оператора, используемых с указателями:
оператор* также известен как оператор разымеения, который используется для объявления переменных-указателей и доступа к значениям, хранящимся по адресу.
运算符& называется оператором адреса и используется для возврата адреса переменной или доступа к адресу переменной через указатель.
Объявление указателя:
var pointer_name *Data_Type
Пример:Ниже приведен указатель типа строки, который может хранить толькоСтрокаадрес переменной.
var s *string
Инициализация указателя:Для этого вам нужно использовать оператор адреса для инициализации указателя адресом другой переменной, как показано в следующем примере:
//обычное объявление переменной var a = 45 //инициализация указателя s //адрес памяти переменной a var s *int = &a
//программа на Golang для демонстрации объявления //и инициализация указателя package main import "fmt" func main() { //определение обычной переменной var x int = 5748 //объявление указателя var p *int //инициализация указателя p = &x //показывать результат fmt.Println("Значение, хранящееся в x, = ", x) fmt.Println("Адрес памяти x = ", &x) fmt.Println("Значение, хранящееся в переменной p, = ", p) }
Вывод:
Значение, хранящееся в x, = 5748 Адрес памяти x = 0xc000066090 Значение, хранящееся в переменной p, = 0xc000066090
Важно:
Значение по умолчанию или нулевое значение указателя всегда nil. Или можно сказать, что неинициализированные указатели всегда имеют значение nil.
//nil значение указателя package main import "fmt" func main() { //определение указателя var s *int //показывать результат fmt.Println("s = ", s) }
Вывод:
s = nil
Объявление и инициализация указателя могут быть выполнены на одном строке.
var s *int = &a
Если нужно одновременно указать тип данных и объявить указатель, указатель сможет обрабатывать адрес памяти переменной указанного типа данных. Например, если вы используете указатель типа строки, то адрес переменной, предоставляемый указателю, будет адресом переменной типа строки, а не другим типом.
Чтобы преодолеть вышеуказанные проблемы, можно использоватьключевое слово varконцепция вывода типа. В процессе объявления не нужно указывать тип данных. Тип переменной-указателя также может быть определен компилятором, как и обычная переменная. В данном случае мы не будем использовать оператор *. При инициализации переменной адресом другого переменного, это будет определено компилятором.
//программа на Golang для демонстрации //в中使用 типовой вывод //переменная-указатель package main import "fmt" func main() { //Использование ключевого слова var //Мы не определили //Любой тип переменной var y = 458 //Использование переменной указателя //Ключевое слово var, не указывающее //Тип var p = &y fmt.Println("Значение, хранящееся в y, = ", y) fmt.Println("Адрес y, = ", &y) fmt.Println("Значение, хранящееся в переменной указателя p, = ", p) }
Вывод:
Значение, хранящееся в y, = 458 Адрес y = 0xc0000120a8 Значение, хранящееся в переменной указателя p, = 0xc0000120a8
Вы также можете использоватьсокращение (:=)грамматика для объявления и инициализации переменной-указателя. Если мы используем&(адрес)Оператор передает адрес переменной, и компилятор определяет переменную как переменную-указатель.
//программа на Golang для демонстрации //в中使用 короткое обозначение //переменная-указатель package main import "fmt" func main() { //Использование оператора := для объявления //И инициализация переменной y := 458 //Использование переменной указателя //Для этого его назначают //Адрес переменной y p := &y fmt.Println("Значение, хранящееся в y, = ", y) fmt.Println("Адрес y, = ", &y) fmt.Println("Значение, хранящееся в переменной указателя p, = ", p) }
Вывод:
Значение, хранящееся в y, = 458 Адрес y = 0xc000066090 Значение, хранящееся в переменной указателя p, = 0xc000066090
Известно, что *оператор также называется оператором dereferencing. Он не только используется для объявления переменных указателей, но и для доступа к значению переменной, на которую указывает указатель, обычно его называютИндирекция или dereferencing.*оператор также называется значением по адресу. Давайте приведем пример, чтобы лучше понять эту концепцию:
//Пример Golang для объяснения этой концепции //Концепция dereferencing package main import "fmt" func main() { //Использование ключевого слова var //Мы не определили //Любой тип переменной var y = 458 //Использование переменной указателя //Ключевое слово var, не указывающее //Тип var p = &y fmt.Println("Значение, хранящееся в y, = ", y) fmt.Println("Адрес y, = ", &y) fmt.Println("Значение, хранящееся в переменной указателя p, = ", p) //Это取消引用 указателя //Использование оператора * до указателя //Переменная используется для доступа к хранящемуся значению //Указывает на переменную fmt.Println("Значение, хранящееся в y (*p), = ", *p) }
Вывод:
Значение, хранящееся в y, = 458 Адрес y = 0xc0000120a8 Значение, хранящееся в переменной указателя p, = 0xc0000120a8 Значение, хранящееся в y (*p), = 458
Вы также можете изменить значение указателя или положение в памяти, а не分配ить новый значений переменной.
package main import "fmt" func main() { //Использование ключевого слова var //Мы не определили //Тип переменной не указан var y = 458 //Использование переменной указателя //Ключевое слово var, не указывающее тип var p = &y fmt.Println("Значение, хранящееся в y до изменения, = ", y) fmt.Println("Адрес y, = ", &y) fmt.Println("Значение, хранящееся в переменной указателя p, = ", p) //Это取消引用 указателя //Использование оператора * до указателя //Переменная используется для доступа к хранящемуся значению //Указывает на переменную fmt.Println("Значение, хранящееся в y(*p) до изменения, = ", *p) //Изменение значения y //Новое значение указателя *p = 500 fmt.Println("Значение, хранящееся в y(*p) после изменения, = ", y) }
Вывод:
Значение, хранящееся в y до изменения, = 458 Адрес y = 0xc0000120a8 Значение, хранящееся в переменной указателя p, = 0xc0000120a8 Значение, хранящееся в y(*p) до изменения, = 458 Значение, хранящееся в y(*p) после изменения, = 500