zoukankan      html  css  js  c++  java
  • 结构体和接口

    1、结构体(struct)定义:就是把使用各种数据类型定义的不同变量组合起来的高级数据类型

    package main
    
    import (
        "fmt"
    )
    
    type Rect struct {
        width, lenght float64
    }
    
    func main() {
        //.形式赋值
        var rect1 Rect
        rect1.width = 100
        rect1.lenght = 200
        fmt.Println(rect1.width * rect1.lenght)
        //Key/value形式赋值
        rect2 := Rect{ 100, lenght: 200}
        fmt.Println(rect2.width * rect2.lenght)
        //依据结构体内变量顺序赋值
        rect3 := Rect{100, 200}
        fmt.Println("Width:", rect3.width, "Length:", rect3.lenght, "Area:", rect3.width*rect3.lenght)
    }

    结果图

    2、结构体作为参数传入函数,即对上面求面积封装为函数

    package main
    
    import (
        "fmt"
    )
    
    type Rect struct {
        width, length float64
    }
    
    func double_are(rect Rect) float64 {
        rect.width *= 2
        rect.length *= 2
        return rect.width * rect.length
    }
    
    func main() {
        var rect = Rect{100, 200}
        fmt.Println(double_are(rect))
        fmt.Println("Width:", rect.width, "Length:", rect.length)
    }

    结果图

    3、结构体组合函数,也就是通过限定函数调用者是哪个结构体,定义在结构体上面的函数叫做方法(结构体不存在内部函数)

    package main
    
    import (
        "fmt"
    )
    
    type Rect struct {
        width, length float64
    }
    
    func (rect Rect) area() float64 {
        return rect.width * rect.length
    }
    
    func main() {
        var rect = Rect{100, 200}
        fmt.Println("Width:", rect.width, "Length:", rect.length, "Area:", rect.area())
    }

    结构图

    4、结构体和指针,用指针来改变结构体内变量值,如果不改变结构体内变量值,方法的限定类型结构体可以不为指针类型。使用new来创建结构体指针类型

    package main
    
    import (
        "fmt"
    )
    
    type Rect struct {
        width, length float64
    }
    
    //改变Rect内参数值
    func (rect *Rect) double_area() float64 {
        rect.width *= 2
        rect.length *= 2
        return rect.width * rect.length
    }
    
    //不改变Rect内参数值
    func (rect Rect) double_area2() float64 {
        rect.width *= 2
        rect.length *= 2
        return rect.width * rect.length
    }
    
    func main() {
        //使用new创建指针类型
        var rect = new(Rect)
        rect.width = 100
        rect.length = 200
        fmt.Println(*rect)
        //方法的限定类型不是指针类型,则不会改变结构体内参数值
        fmt.Println("Width:", rect.width, "Length:", rect.length, "Area:", rect.double_area2())
        //下面有个很奇怪的现象,是会先运行最后的方法,这样width和length都扩大为2倍
        fmt.Println("Double Width:", rect.width, "Double Length:", rect.length, "Double Area:", rect.double_area())
        fmt.Println(*rect)
    }

    结果图

    5、结构体内嵌类型,在一个结构体内部定义另外一个结构体类型成员

    1)、has-a关系,即iPhone有一个Phone

    package main
    
    import (
        "fmt"
    )
    
    type Phone struct {
        price int
        color string
    }
    
    type IPhone struct {
        phone Phone
        model string
    }
    
    func main() {
        var p IPhone
        p.phone.price = 5000
        p.phone.color = "Black"
        p.model = "iPhone 5"
        fmt.Println("I have a iPhone")
        fmt.Println("Price:", p.phone.price)
        fmt.Println("Color:", p.phone.color)
        fmt.Println("Model:", p.model)
    }

    2)is-a关系,即iPhone也是Phone;假设结构体A内部定义了一个内嵌结构体B,那么A同时也可以调用所有定义在B上面的方法

    package main
    
    import (
        "fmt"
    )
    
    type Phone struct {
        price int
        color string
    }
     func (phone Phone) ringing() {
         fmt.Println("Phone is ringing...")
     }
    type IPhone struct {
        Phone
        model string
    }
    
    func main() {
        var p IPhone
        p.price = 5000
        p.color = "Black"
        p.model = "iPhone 5"
        fmt.Println("I have a iPhone:")
        fmt.Println("Price:", p.price)
        fmt.Println("Color:", p.color)
        fmt.Println("Model:", p.model)
        p.ringing()
    }

    6、接口(interface):接口里面可以定义一组方法,任何其他类型只要能够实现了这些方法就是实现了这个接口

    package main
    
    import (
        "fmt"
    )
    
    type Phone interface {
        call()
        sendMsg()
    }
    
    type NokiaPhone struct {
    }
    
    func (nokiaPhone NokiaPhone) call() {
        fmt.Println("I am Nokia,I can call you")
    }
    
    func (nokiaPhone NokiaPhone) sendMsg() {
        fmt.Println("I am Nokia,I can send message to you")
    }
    
    type IPhone struct {
    }
    
    func (iPhone IPhone) call() {
        fmt.Println("I am iPhone,I can call you")
    }
    
    func (iPhone IPhone) sendMsg() {
        fmt.Println("I am iPhone,I can send message to you")
    }
    
    func main() {
        var phone Phone
    
        //NokiaPhone必须要实现Phone中所有方法,否则报错
        phone = new(NokiaPhone)
        phone.call()
    
        //IPhone必须要实现Phone中所有方法,否则报错
        phone = new(IPhone)
        phone.call()
    }

    7、接口还可以作为结构体成员

    package main
    
    import (
        "fmt"
    )
    
    type Phone interface {
        call()
        sales() int
    }
    
    type NokiaPhone struct {
        price int
    }
    
    func (nokiaPhone NokiaPhone) call() {
        fmt.Println("I am Nokia,I can call you")
    }
    
    func (nokiaPhone NokiaPhone) sales() int {
        return nokiaPhone.price
    }
    
    type IPhone struct {
        price int
    }
    
    func (iPhone IPhone) call() {
        fmt.Println("I am iPhone,I can call you")
    }
    
    func (iPhone IPhone) sales() int {
        return iPhone.price
    }
    
    type Person struct {
        phones []Phone
        name   string
        age    int
    }
    
    func (person Person) total_cost() int {
        var sum = 0
        for _, phone := range person.phones {
            sum += phone.sales()
        }
        return sum
    }
    
    func main() {
        var phones = [5]Phone{
            NokiaPhone{price: 350},
            IPhone{price: 5000},
            IPhone{price: 3400},
            NokiaPhone{price: 450},
            IPhone{price: 5000},
        }
        //注意phones要使用切片phones[:]
        var person = Person{name: "Jemy", age: 20, phones: phones[:]}
        fmt.Println(person.name)
        fmt.Println(person.age)
        fmt.Println(person.total_cost())
    }

    结果图

  • 相关阅读:
    后台管理系统-使用AdminLTE搭建前端
    后台管理系统-创建项目
    C# 抽象类、抽象属性、抽象方法
    LOJ6519. 魔力环(莫比乌斯反演+生成函数)
    LOJ6502. 「雅礼集训 2018 Day4」Divide(构造+dp)
    LOJ6503. 「雅礼集训 2018 Day4」Magic(容斥原理+NTT)
    一些说明
    从DEM数据提取点数据对应的高程
    arcmap如何打开或关闭启动时的“getting started”界面
    python如何从路径中获取文件名
  • 原文地址:https://www.cnblogs.com/hujiapeng/p/9648151.html
Copyright © 2011-2022 走看看