go入门(五) 2018-07-19

2018-07-19  本文已影响0人  Yao_oaY

方法和接口

方法

Go语言中没有类,但是可以在结构类型上定义方法,实际上可以对包中的任意类型定义任意方法,但是不能对来自其他包的类型或基础数据类型来定义方法

方法的接收者

方法的接收者可以是指针类型,也可以是值类型

为什么要使用指针作为方法的接收者?

- 避免在每个方法调用中拷贝值
- 方法可以修改接收者指向的值

两种实现方式的对比

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X * v.X + v.Y * v.Y)
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(5)
    fmt.Println(v, v.Abs())    // &{15 20} 25
}


import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X * v.X + v.Y * v.Y)
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(5)
    fmt.Println(v, v.Abs())    // &{3 4} 5
}

对比传值和传地址的结果,可以发现传值的方式读入的v是v的副本,因而无法修改原始值,经过scale之后v的原始值并没有发生变化

接口

接口类型是由一组方法构成的集合,任何实现了接口中所有的方法的值都可以用接口的值来接收

package main

import (
    "fmt"
    "math"
)

type Abser interface {
    Abs() float64
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
    if (f < 0) {
        return float64(-f)
    }
    return float64(f)
}

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X * v.X + v.Y * v.Y)
}

func main() {
    var a Abser
    f := MyFloat(math.Sqrt2)
    v := Vertex{3, 4}

    a = f
    fmt.Println(a.Abs())
    a = &v
    fmt.Println(a.Abs())
}

接口的实现是隐式的,隐式接口解耦了实现接口的包和定义接口的包,互不依赖

空接口

interface{}空接口是指不包含任何方法的接口,空接口可以接收任何类型。常用来处理类型未知的值

空接口结合switch进行类型匹配

package main

import (
    "fmt"
)

func identifyType(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Println("An int:", v)
    case float64:
        fmt.Println("A float64:", v)
    case string:
        fmt.Println("A string:", v, "length =", len(v))
    case bool:
        fmt.Println("A bool:", v)
    case rune:
        fmt.Println("A rune:", string(v))
    default:
        fmt.Printf("Unknown type: %T(%v)\n", v, v)
    }
}

type Vertex struct {
    X, Y float64
}

var pt Vertex = Vertex{1, 2}

var i interface{} = map[int]string{1: "hello", 2: "bye"}

func main() {
    identifyType(1200)
    identifyType(12.21)
    identifyType("hello")
    identifyType(true)
    identifyType('p')
    identifyType(func()int{return 1})
    identifyType([]int{1, 2, 3})
    identifyType(map[string]int{"hello": 100, "world": 200})
    identifyType(pt)
    identifyType(i)
}
上一篇 下一篇

猜你喜欢

热点阅读