结构体和接口

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{width: 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())
}

结果图

 

posted @ 2018-09-27 15:15  jiapeng  阅读(1179)  评论(0编辑  收藏  举报