Подпись Мы получили некоторые базовые знания о 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
- Указатель хранит адрес памяти, & — адрес переменной, * — значение памяти, на которое указывает указатель
- Иерархия многоуровневых указателей
- Структуры могут называться типами данных расширения или типами данных-оболочками.
- Структуры используются для определения непримитивных типов данных.
- Базовые операции со структурами (чтение и запись атрибутов, параметры функций, указатели структур)
Если вы признаете, что я сделал, и считаете, что то, что я сделал, полезно для вас, я надеюсь, что вы также можете вознаградить меня чашкой кофе, спасибо.