方法:
1. Go 没有类。然而,可以在结构体类型上定义方法。例如:
- package main
- import (
- "fmt"
- "math"
- )
-
- type Vertex struct {
- X, Y float64
- }
-
- func (v *Vertex) Abs() float64 { //这里面定义了结构提Vertex这个结构体的方法
- return math.Sqrt(v.X*v.X + v.Y*v.Y)
- }
-
- func main() {
- v := &Vertex{3, 4}
- fmt.Println(v.Abs())
- }
//运行结果是 5
2. 可以对包中的 任意 类型(以type定义的类)定义任意方法,而不仅仅是针对结构体。但是,不能对来自其他包的类型或基础类型定义方法。
- package main
- import (
- "fmt"
- "math"
- )
-
- type MyFloat float64
-
- func (f MyFloat) Abs() float64 {
- if f < 0 {
- return float64(-f)
- }
- return float64(f)
- }
-
- func main() {
- f := MyFloat(-math.Sqrt2)
- fmt.Println(f.Abs())过这个接口可以用来自定义fmt.Println()
- }
过这个接口可以用来自定义fmt.Println()
3. 有时候我们需要将接受方法的对象定义为指针,这样可以有两个效果:
1) 可以提高参数传递的效率,不用拷贝。
2) 修改接收者指向的值。
接口:
1. 接口类型是由一种方法定义的集合,接口定义的方式是:type Abser interface { }
例如下面的这段代码
- package main
-
- import (
- "fmt"
- "math"
- )
-
- type Abser interface { //这里定义了接口 Abser,具有方法Abs(), 这个方法分别由MyFloat类以及Vertex类调用
- Abs() float64
- }
-
- func main() {
- var a Abser
- f := MyFloat(-math.Sqrt2)
- v := Vertex{3, 4}
-
- a = f // a MyFloat 实现了 Abser
-
- fmt.Println(a.Abs())
-
-
- a = &v // a *Vertex 实现了 Abse
-
- fmt.Println(a.Abs())
- }
-
- 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)
- }
2. 介绍一个特殊的接口, fmt包中定义的Stringer
type Stringer interface {
String() string
}
通过这个接口可以用来自定义fmt.Println(), 例如下面的这个例子
- package main
-
- import "fmt"
-
- type Person struct {
- Name string
- Age int
- }
-
- func (p Person) String() string {
- return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
- }
-
- func main() {
- a := Person{"Arthur Dent", 42}
- z := Person{"Zaphod Beeblebrox", 9001}
- fmt.Println(a, z)
- }
-
- //输出格式是:
-
- Arthur Dent (42 years) Zaphod Beeblebrox (9001 years)
3. 与此类似的接口是 error 的一个内建的接口, 可用来自定义error 的格式
type error interface {
Error() string
}
//例如下面:
- package main
-
- import (
- "fmt"
- "time"
- )
-
- type MyError struct {
- When time.Time
- What string
- }
-
- func (e *MyError) Error() string {
- return fmt.Sprintf("at %v, %s",
- e.When, e.What)
- }
-
- func run() error {
- return &MyError{
- time.Now(),
- "it didn't work",
- }
- }
-
- func main() {
- if err := run(); err != nil {
- fmt.Println(err)
- }
- }