• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Golang极简入门教程(二):方法和接口

    方法

    在 Golang 中没有类,不过我们可以为结构体定义方法。我们看一个例子:

    复制代码 代码如下:

    package main
     
    import (
        "fmt"
        "math"
    )
     
    type Vertex struct {
        X, Y float64
    }
     
    // 结构体 Vertex 的方法
    // 这里的方法接收者(method receiver)v 的类型为 *Vertex
    func (v *Vertex) Abs() float64 {
        return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
     
    func main() {
        v := Vertex{3, 4}
        fmt.Println(v.Abs())
    }

    在这里方法的接收者使用指针类型而非值类型主要出于以下几点考虑(类似 C/C++ 等语言):

    1.避免方法每次调用时,对接收者的不必要的拷贝
    2.在方法内可以修改接收者的值

    我们可以为任意类型定义方法,但以下情况除外:

    1.如果类型定义在其他包中,不能为其定义方法
    2.如果类型是基础类型,不能为其定义方法

    复制代码 代码如下:

    package main
     
    import (
        "fmt"
        "math"
    )
     
    // 定义一个类型 MyFloat
    type MyFloat float64
     
    // 注意此方法关联的类型是 MyFloat 而不是 *MyFloat
    func (f MyFloat) Abs() float64 {
        if f 0 {
            return float64(-f)
        }
        return float64(f)
    }
     
    func main() {
        f := MyFloat(-math.Sqrt2)
        fmt.Println(f.Abs())
    }

    接口(interface)

    接口也是一种类型(就像结构体一样)。一个接口类型包含了一组方法,一个接口类型能够持有那些实现了这些方法的值。范例:

    复制代码 代码如下:

    // 定义接口 Abser
    type Abser interface {
        Abs() float64
    }
     
    // 定义结构体 Vertex
    type Vertex struct {
        X, Y float64
    }
     
    // 实现方法 Abs
    func (v *Vertex) Abs() float64 {
        return math.Sqrt(v.X*v.X + v.Y*v.Y)
    }
     
    func main() {
        v := Vertex{3, 4}
        // 成功,能够持有 *Vertex 类型的值
        var a Abser = v
        // 出错,不能持有 Vertex 类型的值
        // 因为在 *Vertex 上定义了方法 Abs,而未在 Vertex 上定义
        var b Abser = v
    }

    错误

    Golang 提供了一个 error 接口:

    复制代码 代码如下:

    type error interface {
        Error() string
    }

    我们通过 os.Open 函数来了解一下 error 的用法:

    复制代码 代码如下:

    // 此函数用于打开一个文件
    // 返回的第二个值为 error 类型
    func Open(name string) (file *File, err error)

    简单的例子:

    复制代码 代码如下:

    package main
     
    import (
        "fmt"
        "os"
    )
     
    func main() {
        _, err := os.Open("test.txt")
        // 如果 err 不为 nil 表示存在错误
        if err != nil {
            fmt.Println(err)
        }
    }

    创建一个 error 值的最简单方式是使用 errors.New 函数:

    复制代码 代码如下:

    func Sqrt(f float64) (float64, error) {
        if f 0 {
            // 出错时返回一个错误
            return 0, errors.New("math: square root of negative number")
        }
        // ...
    }

    我们也可以定义一个新的 error 的实现(也就是实现接口 error):
    复制代码 代码如下:

    type NegativeSqrtError float64
     
    func (f NegativeSqrtError) Error() string {
        return fmt.Sprintf("math: square root of negative number %g", float64(f))
    }

    匿名域

    结构体中可以存在只有类型而没有名字的域,它们被叫做匿名域。例如:

    复制代码 代码如下:

    struct {
        T1
        *T2
    }

    一个结构体的匿名域中的域或者方法可以被此结构体实例直接访问:

    复制代码 代码如下:

    package main
     
    import "fmt"
     
    type Car struct {
        wheelCount int
    }
     
    func (car *Car) numberOfWheels() int {
        return car.wheelCount
    }
     
    type Ferrari struct {
        Car
    }
     
    func main() {
        f := Ferrari{Car{4}}
        fmt.Println("A Ferrari has this many wheels: ", f.numberOfWheels())
    }

    您可能感兴趣的文章:
    • golang分层测试之http接口测试入门教程
    • golang编程入门之http请求天气实例
    • Golang极简入门教程(四):编写第一个项目
    • Golang极简入门教程(三):并发支持
    • Golang极简入门教程(一):基本概念
    • golang特有程序结构入门教程
    上一篇:Golang极简入门教程(一):基本概念
    下一篇:Golang极简入门教程(三):并发支持
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Golang极简入门教程(二):方法和接口 Golang,极简,入门教程,二,