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)
}