golang结构体

结构体是自定义的数据类型,表明一类事物,
结构体变量(实例)是具体的,实际的,表明一个具体变量程序员

type Cat struct {
    Name string
    Age int
    Color string
    Hobby string
}
func main() {
    var cat Cat
    cat.Name = "小黑"
    cat.Age = 34
    cat.Color = "黑色"
    cat.Hobby = "miao"
}

1、结构体变量内存布局

结构体是值类型
image
在建立一个结构体变量后,若是没有给字段赋值,都对应一个零值(默认值):
指针、slice和map的零值都是nil,即尚未分配空间golang

2、建立结构体实例的方式

  1. 方式一
var person Person
person.name = ""
person.age = 34
  1. 方式二
var person Person = {}
person.name = ""
person.age = 34
  1. 方式三
var person *Person = new(Person)
// p3是一个指针,也可person.name = "simon"
go设计者为了简化底层会加上取值符
(*person).name = "simon"
(*person).age = 34
  1. 方式四
var person *Person = &Person{}
// p3是一个指针
(*person).name = "simon"
(*person).age = 34
  • 建立结构体实例时,能够直接指定字段的值
var stu1 Student = Student{"tom", 10}
stu2 := Student{"tom", 10}

// 指针变量
var stu3 *Student = &Student{"xiaomi", 14}

2、结构体使用细节

  • 结构体的全部字段在内存中是连续的
  • 结构体使用户单独定义的类型,和其余类型进行转换时须要彻底相同的字段(名字、个数、类型)
type A struct {
    Num int
}
type B struct {
    Num int
}
func main() {
   var a A
   var a B
   a = B(b) // 要强制转换
}
  • 结构体的每一个字段上,能够写一个tag,该tag能够经过反射机制获取,常见场景序列化和反序列化
type Student struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

3、结构体方法

golang中的方法是做用在指定的数据类型上的(即:和指定的数据类型绑定),所以自定义类型,都有方法,而不单单是structjson

type A struct {
    Num int
}

func (a A) test() {
    fmt.Println(a.Num)
}

func (a A) test() {} 表示A结构体有一个方法名,方法名为test
(a A) 体现test方法是和A类型绑定的编辑器

  • 方法调用和传参机制
  1. 在经过一个变量去调用方法时,其调用机制和函数同样
  2. 不同的地方,变量调用方法时,该变量自己也会做为一个参数传递到方法(若是变量是值类型,则进行值拷贝,若是变量是引用类型,则进行地址拷贝)
  • 方法注意事项和使用细节

若是程序员但愿在方法中,修改结构体变量的值,能够经过结构体指针的方式处理函数

type Circle struct {
    radius float64
}

func (c *Circle) area() float64 {
    // c 是指针, 访问字段的方式是(*c).radius
    // (*c).radius 等价 c.radius
    return 3.14 * (*c).radius * (*c).radius
}
func main() {
    var c Circle
    c.radius = 5.0
    // 编辑器底层做了优化 (&c).area() 等价 c.area()
    res := (&c).area()
}

4、继承

结构体可以使用嵌套匿名结构体全部的字段和方法,(首字母大小写均可使用)布局

type A struct {
    Name string
    age int
}

type B struct {
    A // 嵌套匿名结构体A,达到继承
}

func (a *A) hello() {
    fmt.Println("你好")
}

func main() {
    var b B
    b.A.Name = "xiaoming"
    b.hello()
}

5、接口

interface类型默认是一个指针(引用类型),若是没初始化就是用,会输出nil。
空接口interface{},没有任何方法,全部类型都实现了空接口,便可把任何类型变量赋值给空接口优化

type AInterface interface {
    test1()
}

type BInterface struct {
    test2()
}

type CInterface struct {
    AInterface // 继承另外一个接口
    BInterface
    test3()
}

type Stu struct {

}

func (stu Stu) test1() {

}

func (stu Stu) test2() {
    
}

func (stu Stu) test3() {
    
}

func main() {
    var stu Stu
    var a AInterface = stu
    a.test1()
}

6、断言

因为接口是通常类型,不知道具体类型,若是要转成具体类型,就须要使用类型断言spa

func main() {
    var t float32
    var x interface{}
    x = t
    y, ok := x.(float32) // 转成float32
    if ok == true {
        fmt.Println("convert success")
    } else {
        fmt.Println("convert fail")
    }
}
相关文章
相关标签/搜索