English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang базовый учебник

Golang управляющие выражения

Golang функции & методы

Golang структуры

Golang срезы & массивы

Golang строки(String)

Golang указатели

Golang интерфейсы

Golang параллелизм

Golang исключение(Error)

Другие杂项 Golang

Указатели (Pointer) языка Go

Указатель в языке программирования 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

Указатель — это особый вид переменной, который не только хранит адрес других переменных, но и указывает на положение в памяти, предоставляя способ поиска значения, хранящегося в этом положении памяти. Он обычно называется особым типом переменной, так как он почти как переменная, но с*(оператор разымеения).

DECLAREЦИЯ И ИНИЦИАЛИЗАЦИЯ УКАЗATEЛЯ

Прежде чем начать, мы рассмотрим два важных оператора, используемых с указателями:

оператор* также известен как оператор разымеения, который используется для объявления переменных-указателей и доступа к значениям, хранящимся по адресу.

运算符& называется оператором адреса и используется для возврата адреса переменной или доступа к адресу переменной через указатель.

Объявление указателя:

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

pointer dereferencing

Известно, что *оператор также называется оператором 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