Go语言方法应用

幸运草 2020年4月18日23:07:54函数代码评论阅读模式

Go语言方法应用

匿名字段

Go语言支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。

当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。

Go语言匿名字段可以像字段成员那样访问匿名字段方法,编译器负责查找。

package main

import "fmt"

type Student struct {
    id   int
    name string
}

type Course struct {
    Student
}

func (self *Student) ToString() string {
    return fmt.Sprintf("Student: %p, %v", self, self)
}

func main() {
    c := Course{Student{1, "oldboy"}}
    fmt.Printf("Course: %pn", &c)
    fmt.Println(c.ToString())
}

运行结果:

Class: 0xc0420023e0
User: 0xc0420023e0, &{1 oldboy}

Go 语言不像其它面相对象语言一样可以写个类,然后在类里面写一堆方法,但其实Go语言的方法很巧妙的实现了这种效果:我们只需要在普通函数前面加个接受者(receiver,写在函数名前面的括号里面),这样编译器就知道这个函数(方法)属于哪个struct了。

继承复用

Go语言中没有继承,但是可以依靠组合来模拟继承和多态。

通过匿名字段,可获得和继承类似的复用能力。依据编译器查找次序,只需在外层定义同名方法,就可以实现。

package main

import "fmt"

type Student struct {
    id   int
    name string
}

type Course struct {
    Student
    title string
}

func (self *Student) ToString() string {
    return fmt.Sprintf("Student: %p, %v", self, self)
}

func (self *Course) ToString() string {
    return fmt.Sprintf("Course: %p, %v", self, self)
}

func main() {
    c := Course{Student{1, "oldboy"}, "Golang"}

    fmt.Println(c.ToString())

    fmt.Println(c.Student.ToString())
}

运行结果:

Course: 0xc04207e060, &{{1 oldboy} Golang}
Student: 0xc04207e060, &{1 oldboy}

自定义ERROR
错误是可以用字符串描述自己的任何东西。 可以由预定义的内建接口类型 error,和其返回字符串的方法 Error 构成。

type error interface {
Error() string
}

当用 fmt 包的多种不同的打印函数输出一个 error 时,会自动的调用该方法。

package main

import (
    "fmt"
    "os"
    "time"
)

type PathError struct {
    path       string
    op         string
    createTime string
    message    string
}

func (p *PathError) Error() string {
    return fmt.Sprintf("path=%s nop=%s ncreateTime=%s nmessage=%s", p.path,
        p.op, p.createTime, p.message)
}

func Open(filename string) error {

    file, err := os.Open(filename)
    if err != nil {
        return &PathError{
            path:       filename,
            op:         "read",
            message:    err.Error(),
            createTime: fmt.Sprintf("%v", time.Now()),
        }
    }

    defer file.Close()
    return nil
}

func main() {
    err := Open("/oldboy/golang.go")
    switch v := err.(type) {
    case *PathError:
        fmt.Println("get path error,", v)
    default:
    }
}

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
幸运草
Go语言中的常量 函数代码

Go语言中的常量

1 概述 常量,一经定义不可更改的量。功能角度看,当出现不需要被更改的数据时,应该使用常量进行存储,例如圆周率。从语法的角度看,使用常量可以保证数据,在整个运行期间内,不会被更改。例如当前处理器的架构...
Go语言的接口 函数代码

Go语言的接口

Go语言-接口 在Go语言中,一个接口类型总是代表着某一种类型(即所有实现它的类型)的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干方法声明...
Go语言支持的正则语法 函数代码

Go语言支持的正则语法

1 字符 语法 说明 . 任意字符,在单行模式(s标志)下,也可以匹配换行 字符类 否定字符类 d Perl 字符类 D 否定 Perl 字符类 ASCII 字符类 否定 ASCII 字符类 pN U...
Go语言的包管理 函数代码

Go语言的包管理

1 概述 Go 语言的源码复用建立在包(package)基础之上。包通过 package, import, GOPATH 操作完成。 2 main包 Go 语言的入口 main() 函数所在的包(pa...

发表评论