【新人系列】Golang 入门(十二):指针和结构体 - 上

✍ 个人博客:https://blog.csdn.net/Newin2020?type=blog

📝 专栏地址:https://blog.csdn.net/newin2020/category_12898955.html

📣 专栏定位:为 0 基础刚入门 Golang 的小伙伴提供详细的讲解,也欢迎大佬们一起交流~

📚 专栏简介:在这个专栏,我将带着大家从 0 开始入门 Golang 的学习。在这个 Golang 的新人系列专栏下,将会总结 Golang 入门基础的一些知识点,并由浅入深的学习这些知识点,方便大家快速入门学习~

❤️ 如果有收获的话,欢迎点赞 👍 收藏 📁 关注,您的支持就是我创作的最大动力 💪

1. 指针

1.1 指针的定义和初始化

定义:

go 复制代码
type Person struct {
    name string
}

func changeName(p *Person) {
    p.name = "imooc"
}

func main() {
    p := Person {
        name:"bobby",
    }
    changeName(&p)
    fmt.Println(p.name)    //imooc
}

初始化:

go 复制代码
//方法1
ps := &Person {}

//方法2
var emptyPerson Person
ps := &emptyPerson

//方法3
var ps = new(Person)

注意:

  1. 指针初始化推荐使用 new 函数。
  2. 指针要初始化,否则会出现 nil pointer。

通过 swap 交换指针的值:

go 复制代码
func swap1(a, b *int) {
    a, b = b, a
}

func swap2(a, b *int) {
    t := *a
    *a = *b
    *b = t
}

func main() {
    a, b := 1, 2
    swap1(&a, &b)
    fmt.Println(a, b)    //1 2
    
    c, d := 1, 2
    swap2(&c, &d)
    fmt.Println(c, d)    //2 1
}

注意:

swap1 并不能真正交换两个指针的值,因为它只是交换了两个指针的地址,但其中的值并没有改变。故需要和普通变量交换方法一样,即 swap2 要通过一个临时变量进行交换。

1.2 nil 在 go 中的细节

不同类型的数据零值不一样:

  1. bool:flase
  2. numbers:0
  3. string:""
  4. pointer、slice、map、channel、interface、function:nil

slice 的默认值:

go 复制代码
var ps1 []Person //nil slice -> ps1 == nil
var ps2 = make([]Person,0)    //empty slice -> ps2 != nil

之所以 ps2 不为 nil,是因为它的 slice 结构体中的指针已经不指向 nil,即使分配的空间为 0,它仍然会指向一个分配好的地方。

注意:

map 和 slice 同理,即 m = make(map[string]string, 0) 中的 m 也不等于 nil,它是 empty map。

2. 结构体

2.1 type 关键字

在 Go 语言中,type是一个重要而且常用的关键字。它可以用于定义结构体、类型别名、方法等。

2.1.1 定义结构体

go 复制代码
type person struct { 
    name string // 注意后面不能有逗号 
    age  int 
}

2.1.2 定义类型别名、类型定义

go 复制代码
//定义类型别名 - 别名实际上是为了更好的理解代码
type MyInt = int
var i MyInt = 12
var int = 8
fmt.Println(i + j)
fmt.Printf("%T", i)    //int

//类型定义
type MyInt int
var i MyInt = 12
var j int = 8    //j不能和i直接相加,因为类型不同
fmt.Println(int(i) + j)    //需要强制类型转换
fmt.Printf("%T", i)        //main.MyInt

注意:

在编译的时候,类型别名会被直接替换成对应类型。

自定义类型的应用场景:

可以定义方法,扩展能力,从而使自定义类型能够调用原始类型没有的方法。

go 复制代码
type MyInt int

func (mi MyInt) string() string {
    return strconv.Itoa(int(mi))
}

//调用
var i MyInt = 12
fmt.Println(i.string())

2.1.3 定义方法

go 复制代码
type name string 
func (n name) len() int { 
    return len(n) 
}

2.1.4 类型判断

go 复制代码
var a interface{} = "abc"
switch a.(type) {
case string:
    fmt.Println("字符串")
}

2.2 结构体的定义和初始化

结构体(Struct)是一种将不同类型的数据组合在一起的复合数据类型。

结构体可以包含各种类型的字段,例如整数、浮点数、字符串、布尔值,甚至其他结构体或指针等。

2.2.1 定义

go 复制代码
type Person struct {
    name string
    age int
    address string
    height float32
}

2.2.2 初始化

go 复制代码
//方法1
p1 := Person {"bobby1", 18, "慕课网", 1.80}

//方法2
p2 := Person {
    name:"bobby2",
    height:1.78,
}

注意:

初始化方法 1 需要将所有值给初始化,方法 2 则可以只初始化部分值,并且可以选择初始值。

2.2.3 匿名结构体

go 复制代码
address := struct {
    province string
    city string
    address string
}{
    "北京市",
    "通州区",
    "xxx",
}

2.2.4 结构体嵌套

go 复制代码
type Student struct {
    p Person
    score floast32
}

s := Student {
    Person {
        "bobby", 18,
    },
    95.6,
}

fmt.Println(s.p.age)

2.2.5 匿名嵌套

go 复制代码
type Student struct {
    Person    //这里直接写结构体名称
    score floast32
}

s := Student {
    Person {
        "bobby", 18,
    },
    95.6,
}

fmt.Println(s.age)    //用的时候就不用加p了
相关推荐
莎士比亚的文学花园18 分钟前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
图码26 分钟前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
U盘失踪了32 分钟前
python curl转python脚本
开发语言·chrome·python
charlie11451419132 分钟前
Linux 字符设备驱动:cdev、设备号与设备模型
linux·开发语言·驱动开发·c
handler0134 分钟前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
FQNmxDG4S35 分钟前
Java泛型编程:类型擦除与泛型方法的应用场景
java·开发语言·python
我星期八休息1 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
热心网友俣先生1 小时前
2026年第二十三届五一数学建模竞赛C题超详细解题思路+各问题可用模型推荐+部分模型结果展示
c语言·开发语言·数学建模
01漫游者1 小时前
JavaScript函数与对象增强知识
开发语言·javascript·ecmascript
IGAn CTOU1 小时前
Java高级开发进阶教程之系列
java·开发语言