Golang 结构体笔记

结构体是一个自定义的数据类型,是值类型

声明结构体

type 结构体名称 struct {

field_1 type

field_2 type

}

注意事项

  1. 字段声明语法同变量,示例:字段名 字段类型

  1. 字段的类型可以为:基本类型、数组或引用类型

  1. 创建一个结构体变量后,如果没有给字段赋值,都会对应一个默认值,规则如下:

  • 布尔类型默认为false

  • 数值类型默认为0

  • 字符串类型默认为空""

  • 数组类型的默认值与它的元素类型相关,比如:Scores [3]int 默认值为:[0,0,0]

  • 指针、切片(slice)、map默认值都是nil,即还没有分配空间

  1. 不同的结构体字段之间是独立的,互不影响,一个字段值的改变不会影响另外一个

基本使用

package main

import "fmt"

type Stu struct {
    Name  string
    Age   int
    Score float32
    Ptr   *int              // 指针
    Array [3]int            // 数组
    Slice []string          // 切片
    Map1  map[string]string // map
}

func main() {
    // 结构体基本使用
    var student Stu
    student.Name = "宋江"
    student.Age = 20
    student.Score = 60

    fmt.Println(student)
    // 单独访问变量
    fmt.Printf("Name:%v,Age:%v,Score:%v\n", student.Name, student.Age, student.Score)
    // 给数组赋值
    student.Array = [3]int{1, 2, 0}
    student.Array[2] = 3
    // 给切片赋值,切片赋值必须make!!!
    student.Slice = make([]string, 3)
    student.Slice[0] = "卢俊义"
    student.Slice[1] = "吴用"
    student.Slice[2] = "公孙胜"
    student.Slice = append(student.Slice, "林超") // 切片超过定义范围,再追加需用append函数
    // 给map赋值,map赋值必须make!!!
    student.Map1 = make(map[string]string)
    student.Map1["no1"] = "吃饭"
    student.Map1["no2"] = "睡觉"
    student.Map1["no3"] = "打游戏"
    fmt.Println(student)
}

不同的结构体字段之间是独立性

package main

import "fmt"

type Stu struct {
    Name  string
    Age   int
    Score float32
}

func main() {
    // 不同的结构体字段之间是独立的,互不影响
    var student1 Stu
    student1.Name = "宋江"
    student1.Age = 20
    student1.Score = 60

    student2 := student1
    student2.Score = 70 // 此处元素值的改变并不会影响student1
    fmt.Println(student1)
    fmt.Println(student2)
}

创建结构体实例的四种方式

看代码注释,推荐第二种方式

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    // 第一种方式
    var person1 Person
    person1.Name = "宋江"
    person1.Age = 20
    fmt.Println(person1)

    // 第二种方式
    var person2 = Person{
        Name: "吴用",
        Age:  19,
    }
    fmt.Println(person2)

    // 第三种方式,person3是指针类型
    var person3 *Person = new(Person) // *Person可以省略不写
    (*person3).Name = "卢俊义"           // 可以省略为:person3.Name = "卢俊义",(*person3)等价于person3
    (*person3).Age = 21               // 可以省略为:person3.Age = 21,(*person3)等价于person3
    fmt.Println(*person3)

    // 第四种,person4算指针类型,可以直接赋值,也可以重新赋值
    var person4 *Person = &Person{ // *Person可以省略不写
        Name: "公孙胜",
        Age:  22,
    }
    person4.Name = "林冲" // 重写赋值,标准写法:(*person4).Name = "林冲",这里使用的是省略方式
    person4.Age = 23    // 重写赋值,标准写法:(*person4).Age = 23,这里使用的是省略方式
    fmt.Println(*person4)
}

结构体指针的使用

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    var person = Person{
        Name: "宋江",
        Age:  19,
    }
    personPtr := &person  // 定义一个指针
    personPtr.Name = "吴用" // 修改指针的Name,personPtr是省略方式
    (*personPtr).Age = 20 // 修改指针的Age,*personPtr是指针标准方式
    fmt.Println(person)
    fmt.Println(*personPtr)
}

结构体细节

  1. 结构体是用户单独定义的类型,和其他类型进行转换时需要有完全相同的字段(字段名、个数、类型)

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

type Person1 struct {
    Name string
    Age  int
}

func main() {
    var person = Person{
        Name: "宋江",
        Age:  19,
    }
    // var person1 Person1 = person // 这种直接赋值是不行的,需要做强转
    var person1 Person1 = Person1(person) // 强转的前提是两个结构体必须完全一样
    fmt.Println(person)
    fmt.Println(person1)
}
  1. 结构体进行type重新定义(相当于取别名),Golang认为是新的数据类型,但是相互间可以强转

package main

import "fmt"

type integer int // 新定义数据类型integer,相当于int的别名

func main() {
    var i integer = 10
    var j int
    // j = i // 直接赋值是不行,需要强转
    j = int(i)
    fmt.Println(i, "---", j)
}
  1. struct 的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景是json的序列化和反序列化

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json:"name"` // tag的作用是返回json后Name转换为name(首字母小写)
    Age  int    `json:"age"`
    As   string `json:"as"`
}

func main() {
    var persons = map[int]Person{
        0: {
            Name: "宋江",
            Age:  19,
            As:   "及时雨",
        },
        1: {
            Name: "吴用",
            Age:  20,
            As:   "神机军师",
        },
    }
    var personStr, err = json.Marshal(persons)
    if err != nil {
        fmt.Println("json转码错误", err)
    } else {
        fmt.Println(string(personStr))
    }
}

返回:{"0":{"name":"宋江","age":19,"as":"及时雨"},"1":{"name":"吴用","age":20,"as":"神机军师"}}

创建struct实例指定字段值

分值、指针两种,分别对应四种方式

package main

import "fmt"

type Student struct {
    Name string
    Age  int
}

func main() {
    // 返回结构体的值类型
    var stu = Student{"宋江", 20} // 必须严格按照struct定义的顺序,不灵活
    stu1 := Student{"卢俊义", 19}  // 必须严格按照struct定义的顺序,不灵活
    var stu2 = Student{
        Name: "公孙胜",
        Age:  21,
    }
    stu3 := Student{
        Age:  22,
        Name: "林冲",
    }
    fmt.Printf("stu=%v,stu1=%v,stu2=%v,stu3=%v\n", stu, stu1, stu2, stu3)
    // 返回结构体的指针类型
    var stu4 = &Student{"武松", 19}
    stu5 := &Student{"鲁智深", 30}
    var stu6 = &Student{
        Name: "林冲",
        Age:  23,
    }
    stu7 := &Student{
        Age:  18,
        Name: "燕青",
    }
    fmt.Printf("stu4=%v,stu5=%v,stu6=%v,stu7=%v\n", *stu4, *stu5, *stu6, *stu7)
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值