首页 > 其他分享 >Golang:3.6、Golang 结构体 struct

Golang:3.6、Golang 结构体 struct

时间:2022-10-22 19:37:31浏览次数:60  
标签:3.6 struct Person fmt Golang person Printf main name

3.6、Golang 结构体 struct

类型定义和类型别名

类型定义的语法

type NewType Type

示例

package main

import "fmt"

func main() {
    // 定义类型
    type MyInt int

    var i MyInt

    i = 100
    fmt.Printf("%T", i)
    // main.MyInt
}

类型别名语法

type NewType = Type

示例

package main

import "fmt"

func main() {
    // 定义类型别名
    type MyInt = int

    var i MyInt

    i = 100
    fmt.Printf("%T", i)
    // int
}

类型定义和类型别名的区别

  • 类型定义相当于定义了一个全新的类型
  • 类型别名只会在代码中存在,编译完成后并不会存在
  • 类型别名可以使用原来类型所有的方法

Golang结构体

golang中没有面向对象的概念,但是可以使用结构体来实现,面向对象编程的一些特性,例如:继承、组合等

结构体的定义

type struct_variable_type struct {
    // 成员
    member definition;
    member definition;
    ...
    member definition;
}

示例

// 定义一个结构体Person
type Person struct {
    id    int
    name  string
    age   int
    email string
}

// 可以把相同类型的成员合并到一行
type Person struct {
    id, age     int
    name, email string
}

声明结构体变量

var tom Person

fmt.Printf("%v", tom)
// {0 0  }

jack := Person{}
fmt.Printf("%v", jack)
// {0 0  }

访问结构体成员

package main

import "fmt"

// 定义一个结构体Person

// 可以把相同类型的成员合并到一行
type Person struct {
    id, age     int
    name, email string
}

func main() {
    var tom Person

    tom.id = 12
    tom.name = "Tom"
    tom.age = 23
    tom.email = "[email protected]"

    fmt.Printf("%v", tom)
    // {12 23 Tom [email protected]}

}

匿名结构体

package main

import "fmt"


func main() {
    var dog struct {
        id   int
        name string
    }

    dog.id = 12
    dog.name = "Tom"

    fmt.Printf("%v", dog)
    // {12 Tom}

}

Golang结构体的初始化

未初始化的结构体,成员都是零值

使用键值对的方式初始化

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {
    tom := Person{
        id:    12,
        age:   23,
        name:  "Tom",
        email: "[email protected]",
    }

    fmt.Printf("%v", tom)
    // {12 23 Tom [email protected]}

}

使用值的列表初始化

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {
    tom := Person{
        12,
        23,
        "Tom",
        "[email protected]",
    }

    fmt.Printf("%v", tom)
    // {12 23 Tom [email protected]}

}

部分成员初始化

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {
    tom := Person{
        id:   12,
        name: "Tom",
    }

    fmt.Printf("%v", tom)
    // {12 0 Tom }

}

Golang结构体的指针

普通指针

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {
    // 定义字符串变量
    var name string
    name = "Tom"

    // 定义字符串类型的指针变量
    var name_ptr *string
    name_ptr = &name

    // 变量的值
    fmt.Printf("%v\n", name)
    // Tom

    // 指针地址
    fmt.Printf("%v\n", name_ptr)
    // 0xc000014250

    // 指针指向的变量值
    fmt.Printf("%v\n", *name_ptr)
    // Tom
}

结构体的指针

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {

    // 结构体变量
    person := Person{
        id:    11,
        name:  "Tom",
        age:   23,
        email: "[email protected]",
    }

    // 指针变量
    var person_ptr *Person
    person_ptr = &person

    // 变量的值
    fmt.Printf("%v\n", person)
    // {11 23 Tom [email protected]}

    // 指针地址
    fmt.Printf("%p\n", person_ptr)
    // 0xc00009a180

    // 指针指向的变量值
    fmt.Printf("%v\n", *person_ptr)
    // {11 23 Tom [email protected]}
}

使用new关键字创建结构体指针

package main

import "fmt"

// 定义一个结构体Person
type Person struct {
    id    int
    age   int
    name  string
    email string
}

func main() {

    var person = new(Person)

    // 访问结构体指针成员,可以省略*
    // 自动解引用
    (*person).age = 23
    person.id = 12
    person.name = "Tom"

    fmt.Printf("%T\n", person)
    // *main.Person

    fmt.Printf("%v\n", person)
    // &{12 0 Tom }

    fmt.Printf("%v\n", *person)
    // {12 0 Tom }
}

结构体作为函数参数

结构体作为参数传递给函数

  • 直接传递结构体,传递的是副本,函数内部不能改变外部结构体内容
  • 传递结构体指针,函数内部能改变外部结构体内容

值传递

package main

import "fmt"

type Person struct {
    age  int
    name string
}

// 值传递,拷贝了一份副本
func showPerson(person Person) {
    person.age = 12
    person.name = "Jakc"

    fmt.Printf("%v\n", person)
}

func main() {

    person := Person{
        age:  11,
        name: "Tom",
    }

    fmt.Printf("%v\n", person)
    // {11 Tom}

    showPerson(person)
    // {12 Jakc}

    fmt.Printf("%v\n", person)
    // {11 Tom}
}

指针传递

package main

import "fmt"

type Person struct {
    age  int
    name string
}

// 指针传递
func showPerson(person *Person) {
    person.age = 12
    person.name = "Jakc"

    fmt.Printf("%v\n", *person)
}

func main() {

    person := Person{
        age:  11,
        name: "Tom",
    }

    fmt.Printf("%v\n", person)
    // {11 Tom}

    showPerson(&person)
    // {12 Jakc}

    fmt.Printf("%v\n", person)
    // {12 Jakc}
}

结构体的嵌套

示例

package main

import "fmt"

type Dog struct {
    age  int
    name string
}

type Person struct {
    age  int
    name string
    dog  Dog
}

func main() {
    dog := Dog{
        age:  1,
        name: "dog",
    }

    person := Person{
        dog:  dog,
        age:  11,
        name: "Tom",
    }

    fmt.Printf("%v\n", person)
    // {11 Tom {1 dog}}

    fmt.Printf("%v\n", person.dog.name)
    // dog
}


方法

golang中,方法是一种特殊的函数

定义与struct之上(与struct关联、绑定),被称为struct的接受者(receiver)

通俗讲,方法就是有接收者的函数

语法格式

type struct_name struct{}

func (recv struct_name) method_name(param_type) return_type{}

func (recv *struct_name) method_name(param_type) return_type{}
package main

import "fmt"

// 属性和方法分开写
type Person struct {
    age  int
    name string
}

// Person 接收者 receiver
func (person Person) eat() {
    fmt.Printf("%v eat\n", person.name)
}

func (person Person) sleep() {
    fmt.Printf("%v sleep\n", person.name)
}

func main() {

    person := Person{
        age:  11,
        name: "Tom",
    }

    person.eat()
    // Tom eat

    person.sleep()
    // Tom sleep
}

go语言方法的注意事项

  • 方法的receiver type可以是类型别名、struct、slice、map、channel、func等
  • struct结合它的方法等价于面向对象中的类,只不过struct可以和它的方法分开写,并非一定要属于同一个文件,但是,必须属于同一个包
  • 方法有两种接收类型(T type)(T *Type),它们之间有区别
  • 方法就是函数,所有Go中没有方法重载overload的说法,也就是说同一个类型中的所有方法名必须唯一
  • 如果receiver是一个指针类型,则会自动解除引用
  • 方法和type是分开的,意味着实例的行为behavior和数据存储field是分开的,但它们通过receiver建立起关联关系

方法接收者类型

  • 值类型:复制结构体副本
  • 指针类型:不复制
package main

import "fmt"

// Person 接收者 receiver
type Person struct {
    age  int
    name string
}

// 值传递,拷贝了一份副本
func (person Person) showPersonByValue() {
    person.age = 12
    person.name = "Jack"

    fmt.Printf("%v\n", person)
}

// 指针传递
func (person *Person) showPersonByPointer() {
    person.age = 12
    person.name = "Jack"

    fmt.Printf("%v\n", person)
}

func main() {

    person := Person{
        age:  11,
        name: "Tom",
    }

    fmt.Printf("%v\n", person)
    // {11 Tom}

    // 接收者类型是变量,值没有被修改
    person.showPersonByValue()
    // {12 Jack}

    fmt.Printf("%v\n", person)
    // {11 Tom}

    // 接收者类型是指针,值被修改
    person.showPersonByPointer()
    // &{12 Jack}

    fmt.Printf("%v\n", person)
    // {12 Jack}
}

标签:3.6,struct,Person,fmt,Golang,person,Printf,main,name
From: https://blog.51cto.com/mouday/5786055

相关文章

  • Golang:3.7、Golang接口 interface
    3.7、Golang接口interfacego语言中的接口,是一种新的类型定义,它把所有的具有共性的方法定义在一起,任何其他类型制药实现了这些方法就是实现了这个接口语法//定义接口ty......
  • @RequiredArgsConstructor @Autowired
    @RequiredArgsConstructorprivatefinalCppccWyxqTypeServicecppccWyxqTypeService;必须声明的变量为final@AutowiredprivateCppccProposalServicecppccProposa......
  • Golang-Gin Response 统一返回restful格式的数据
    目的:gin返回restful格式的数据,返回的200,201的数据也包括异常时的404/500等情况直接调用即可packageresponseimport( "github.com/gin-gonic/gin" "net/http")......
  • Golang 几个小时前 几分钟 几天前的处理
    在用golang爬虫的时候总会遇到10天前10分钟前刚刚这种很影响我们爬取正常事件所以我写了个方法来格式化这种事件packageutilsimport( "fmt" "regexp" "strco......
  • Golang 和 Python 随机生成N位字符串
    Golang:funcRandomString(nint)string{ varletters=[]byte("ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789") result:=make([]byte,n) /......
  • Golang基础-运算符
    运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等运算符分为:算术运算符:+、-、*、/,%,++,--赋值运算符:=、+=、-=、*=、/=、%=关系运算符:==、!=、>、<、>=、<=......
  • Linux struct sk_buff *skb 结构体
    structsk_buff是linux网络系统中的核心结构体,linux网络中的所有数据包的封装以及解封装都是在这个结构体的基础上进行。sk_buff是Linux网络中最核心的结构体,它用来管理......
  • Golang基础-变量与数据类型
    变量变量的定义1.声明2.赋值3.使用//声明:var变量名变量类型varnamestring//赋值:name="xiaoming"//使用:fmt.Println(name)//声明+赋值//var变......
  • golang中的切片
    索引:https://waterflow.link/articles/1666277946416在go中切片的底层是数组,所以切片的数据连续存储在数组的数据结构中。如果底层的数组满了,切片还需要添加元素的话,底层数......
  • golang中的切片
    索引:https://waterflow.link/articles/1666277946416在go中切片的底层是数组,所以切片的数据连续存储在数组的数据结构中。如果底层的数组满了,切片还需要添加元素的话,底层......