Общее руководство по golang: указатели, структуры

Java задняя часть Go

Подпись Мы получили некоторые базовые знания о golang, и мы ясно видим, что golang и язык c очень похожи, поэтому, когда вы это увидите, вы можете быть еще более шокированы, это может быть новая эра языка c.

указатель

Переменная — это удобный заполнитель для ссылки на адрес памяти компьютера. Адресный символ языка Go — &, который используется перед переменной для возврата адреса памяти соответствующей переменной.

Пример кода выглядит следующим образом:

package main

import "fmt"

func main() {
   var a int = 10   

   fmt.Printf("变量的地址: %x\n", &a  )
}

Вывод выглядит следующим образом, возможно, разные компьютеры здесь имеют разный вывод:

变量的地址: c420014058

Концепция указателя такова: адрес памяти, указывающий на любое значение, которое является номером адреса памяти. Основные моменты:

  • это основной тип данных в go
  • Представляет адрес памяти
  • адрес, который может указывать на произвольные данные
  • Указатели различных типов данных требуют различных комбинаций типов данных и символов указателя для представления.

Давайте рассмотрим несколько простых примеров:

//指针申明格式
// var var_name *var-type
// var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。

var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

Как и другие типы переменных, указатели необходимо объявить и присвоить, прежде чем их можно будет использовать.Взгляните на следующую демонстрацию:

package main

import "fmt"

func main() {

	var a int = 20    /* 声明实际变量 */

	var aPointer *int /* 声明指针变量 */

	aPointer = &a /* 指针变量的存储地址 */

	fmt.Printf("a 变量的地址是: %x\n", &a)

	/* 指针变量的存储地址 */
	fmt.Printf("aPointer 变量储存的指针地址: %x\n", aPointer)

	/* 使用指针访问值 */
	fmt.Printf("*aPointer 变量的值: %d\n", *aPointer)
}

Вывод выглядит следующим образом (разные компьютеры могут иметь разные фактические адреса):

a 变量的地址是: c420014050
aPointer 变量储存的指针地址: c420014050
*aPointer 变量的值: 20

На самом деле, для более подробного изучения использования указателей вы можете посмотреть университетский учебник по языку c и версию структуры данных для языка c.

нулевой указатель

Когда указатель определен без присвоения какой-либо переменной, его значение равно нулю.

Нулевой указатель также известен как нулевой указатель.

nil концептуально совпадает с null, None, nil и NULL в других языках, ссылаясь на нулевое или нулевое значение.

Переменная-указатель часто обозначается аббревиатурой ptr.

Обратите внимание, что указатели также имеют следующие операции:

  • Массив указателей (ядро — массивы и указатели)
  • Многоуровневые указатели (указатели на указатели)
  • параметр указателя функции

Давайте посмотрим на следующий пример:

package main

import "fmt"

func main() {

	var a int = 20 /* 声明实际变量 */

	var aPointer *int /* 声明指针变量 */

	aPointer = &a /* 指针变量的存储地址 */

	fmt.Printf("a 变量的地址是: %x\n", &a)

	/* 指针变量的存储地址 */
	fmt.Printf("aPointer 变量储存的指针地址: %x\n", aPointer)

	/* 使用指针访问值 */
	fmt.Printf("*aPointer 变量的值: %d\n", *aPointer)

	b := 35
	bPointer := &b

	fmt.Printf("a = %d ,b = %d \n", a, b)
	fmt.Printf("aPointer = %x ,bPointer = %x \n", aPointer, bPointer)

	swap(aPointer, bPointer)

	fmt.Println("交换后的结果")
	fmt.Printf("a = %d ,b = %d \n", a, b)
	fmt.Printf("aPointer = %x ,bPointer = %x \n", aPointer, bPointer)

	pBPtr := &bPointer

	fmt.Printf("pBPtr = %x ,*pBPtr = %x  ,**pBPtr = %x \n", pBPtr, *pBPtr, **pBPtr)

}

func swap(a, b *int) {
	tmp := *a

	*a = *b

	*b = tmp
}

Результат вывода: привет:

a 变量的地址是: c420014050
aPointer 变量储存的指针地址: c420014050
*aPointer 变量的值: 20
a = 20 ,b = 35 
aPointer = c420014050 ,bPointer = c420014060 
交换后的结果
a = 35 ,b = 20 
aPointer = c420014050 ,bPointer = c420014060 
pBPtr = c42000c030 ,*pBPtr = c420014060  ,**pBPtr = 14 

В приведенном выше примере мы можем ясно видеть, что значения a и b изменились после обмена, но значения aPointer и bPointer не изменились.

В функции обмена мы напрямую изменили значения a и b с помощью операций над указателями, но aPointer и bPointer указывают на адреса a и b, мы их не меняли, поэтому значения aPointer и bPointer не изменился.

Затем мы объявляем и инициализируем вторичный указатель pBPtr, значением которого является адрес переменной указателя bPointer, а затем значением *pBPtr является адрес, на который указывает bPointer, который является адресом b, поэтому значение **pBPtr является значением b .

структура

Структуры, с которыми мы столкнулись в C, используются для сборки разных данных (независимо от того, один и тот же тип данных или нет). В других объектно-ориентированных языках, таких как java, мы привыкли писать объекты bean-компонентов следующим образом:

//在java中创建Person实体
class Person implements Serializable{
    private String name;
    private Integer age;
}

Итак, как мы работаем на ходу?

type Person struct {
	name string
	age  int
}

Конечно, давайте посмотрим на конкретное демо:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

//这里是方法,输入Person的方法
func (person Person) logPerson() {
	fmt.Printf("%s,年龄:%d", person.name, person.age)
}

func main() {
	var aPerson Person

	aPerson.name = "go语言"
	aPerson.age = 8
	aPerson.logPerson()

}

В приведенном выше коде мы используем некоторые точки знаний:

  • Переменные, объявления и присваивания
  • Имя пакета, пакет импорта, основная функция
  • функция, метод
  • структура

В основной функции мы объявляем переменную aPerson, а тип данных — структура Person. Затем мы инициализируем определенные свойства структуры, а затем вызываем метод самой структуры для вывода соответствующей информации о Person.

Конечно, структура имеет некоторые из следующих операций:

  • доступ к свойству, имя переменной структуры.имя свойства
  • Подобно использованию базовых типов данных (объявление переменных, параметров функций, указателей и т. д.)

Следующая демонстрация в основном иллюстрирует общее использование структур:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

func (person Person) logPerson() {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func printPersonByPointer(person *Person) {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func printPerson(person Person) {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func main() {
	var aPerson Person

	aPerson.name = "go语言"
	aPerson.age = 8
	aPerson.logPerson()

	printPersonByPointer(&aPerson)
	
	printPerson(aPerson)
}

Примечание. В языке go перегрузка функций не поддерживается.

Суммировать

Есть много общего между языком go и языком c. И указатели, и структуры — похожие понятия в языке C.

  • Указатель поддерживает работу с любым типом данных Формат объявления указателя: var *name dataType
  • Указатель хранит адрес памяти, & — адрес переменной, * — значение памяти, на которое указывает указатель
  • Иерархия многоуровневых указателей
  • Структуры могут называться типами данных расширения или типами данных-оболочками.
  • Структуры используются для определения непримитивных типов данных.
  • Базовые операции со структурами (чтение и запись атрибутов, параметры функций, указатели структур)

Если вы признаете, что я сделал, и считаете, что то, что я сделал, полезно для вас, я надеюсь, что вы также можете вознаградить меня чашкой кофе, спасибо.

支付宝捐赠