go 结构体
由一组字段构成的一种自定义数据类型 type User struct { Name string Id uint32 } var u1 User = User{ Name: "张三",
go 结构体
发布时间:2023-10-06 (2023-10-06)

由一组字段构成的一种自定义数据类型

type User struct {
  Name string
  Id uint32
}

var u1 User = User{
  Name: "张三",
}
u1.Id = 10000

结构体字段

结构体可以没有字段

结构体字段通过.访问

继承

package main

import "fmt"

type User struct {
  Name     string
  Age      int
  password string
}

type Account struct {
  User
  money float32
  Name  string
}

func main() {
  var ac Account = Account{
    money: 21.9,
    User: User{
      Name:     "王五",
      Age:      21,
      password: "978345",
    },
    Name: "账户1",
  }
  fmt.Printf("ac %#v, %T\n", ac, ac)
  var u1 = User{
    Name:     "lisa",
    Age:      22,
    password: "1233fg",
  }
  var ac1 Account = Account{
    money: 21.9,
    User:  u1,
  }
  fmt.Printf("ac1 %#v, %T\n", ac1, ac1)

  fmt.Println(ac.money)
  fmt.Println(ac.Name)
  fmt.Println(ac.User.Name)
  fmt.Println(ac.password)
}

方法

package main

import "fmt"

type User struct {
  Name     string
  Age      int
  password string
}

func (u User) PrintName() string {
  u.Name = "张三"
  fmt.Println("printName方法: ", u)
  fmt.Printf("printName方法内部:%p \n", &u)
  return u.Name
}


func main() {
  user := User{"王二麻子", 23, "xsdfe23"}
  fmt.Printf("main: %p\n", &user)
  name := user.PrintName() // 是值传递,
  fmt.Println(name, user)
}

结构体指针

type User struct {
  Name string
  Id   uint16
}

var u User = User{
  Name: "zhangsan",
}
u.Id = 20
fmt.Println(u)
var u2 *User = &User{
  Name: "李四",
}
u2.Id = 21
fmt.Println(u2)

fmt.Printf("u = %+v, type of %T\n", u, u)
fmt.Printf("u2 = %+v, type of %T\n", u2, u2)

继承

type User struct {
  Name string
  Id   uint16
}

type Account struct {
  User
  password string
}

type Contact struct {
  *User
  Remark string
}

// 实例化账户
var a1 = Account{
  User: User{
    Name: "张三",
    Id:   1,
  },
  password: "666",
}
var c1 *Contact = &Contact{
  User:   &a1.User,
  Remark: "王麻子",
}
// 没有重复字段就可以这样简写
c1.Name = "王五" // 等效于  c1.User.Name = "王五"

fmt.Printf("a1 = %+v\n", a1)
fmt.Printf("c1 = %+v\n", c1)

结构体标签

type User struct {
  Name string `json:"name"`
  Id   uint16 `json:"id"`
}

这样写好之后,结构体进行json转换的时候,Name就会自动变为name

package main

import (
  "encoding/json"
  "fmt"
)

type Article struct {
  Title     string `json:"title"`
  Desc      string `json:"desc"`
  Content   string `json:"content"`
  Username  string `json:"-"` // - 也不参与序列化
  LookCount int    `json:"look_count"`
  Free      bool   `json:"free"`
  password  string // 小写字母开头的不会参与序列化
}

func main() {
  article := Article{
    Title:     "golang文档",
    Desc:      "golang零基础入门,四小时转岗golang开发",
    Content:   "golang零基础入门,四小时转岗golang开发",
    Username:  "fengfeng",
    LookCount: 1024,
    password:  "ksd8%38",
    Free:      true,
  }

  // 结构体转json
  jsonData, err := json.Marshal(article)
  if err != nil {
    fmt.Println(err)
    return
  }
  jsonStr := string(jsonData)
  fmt.Println(jsonStr)

}

方法

和函数没什么区别

只是多了一个形参,是和结构体绑定在一起的

package main

import "fmt"

type User struct {
  Name string `json:"name"`
  Id   uint16 `json:"id"`
}

func (u User) PrintName() string {
  return u.Name
}

func main() {
  u := User{
    Name: "张三",
    Id:   1001,
  }
  fmt.Println(u.PrintName())
}

我们都知道golang的函数都是值传递

所以如果在方法中修改结构体的值

相当于修改的是结构体的副本

type User struct {
  Name string `json:"name"`
  Id   uint16 `json:"id"`
}

func (u User) SetName(name string) {
  u.Name = name
  fmt.Printf("setName修改之后:u=%+v\n", u)
}

func main() {
  u := User{
    Name: "张三",
    Id:   1001,
  }
  u.SetName("李四")
  fmt.Printf("setName运行完之后,u=%+v\n", u)
}

如果需要修改原结构体,那么需要传递的是结构体的指针

type User struct {
  Name string `json:"name"`
  Id   uint16 `json:"id"`
}

func (u *User) SetName(name string) {
  (*u).Name = name
  // 也可这样简写
  //u.Name = name
  fmt.Printf("setName修改之后:u=%+v\n", *u)
}

func main() {
  u := User{
    Name: "张三",
    Id:   1001,
  }
  u.SetName("李四")
  fmt.Printf("setName运行完之后,u=%+v\n", u)
}