嵌套方法
//毕达哥拉斯定理
package main
import (
"fmt"
"math"
)
type Point struct {
x, y float64
}
func (p *Point) Abs() float64 {
return math.Sqrt(p.x*p.x + p.y*p.y)
}
type NamedPoint struct {
Point
name string
}
func main() {
n := &NamedPoint{Point{3, 4}, "Pythagoras"}
fmt.Println(n.Abs()) // 打印5
fmt.Println(n.name)
}
output
5
Pythagoras
对于接口,类型(比如结构体)实现接口方法集中的方法,每一个方法的实现说明了此方法是如何作用于该类型的:即实现接口,同时方法集也构成了该类型的接口。
下面是求矩形面积的一个实例:
//计算矩形面积,没用接口
package main
import "fmt"
type Square struct{
side float64
}
type Rectangle struct{
length float64
width float64
}
func (sq *Square)Area()float64{
return sq.side*sq.side
}
func (r *Rectangle)Area()float64{
return r.length*r.width
}
func main(){
a := &Rectangle{2,3}
b := &Square{5}
fmt.Println(a.Area(),b.Area())
}
//output:6 25
下面是用接口的代码:
package main
import "fmt"
type Shaper interface{
Area()float64
}
type Square struct{
side float64
}
type Rectangle struct{
length float64
width float64
}
func (sq *Square)Area()float64{
return sq.side*sq.side
}
func (r *Rectangle)Area()float64{
return r.length*r.width
}
func main(){
a := &Rectangle{2,3}
b := &Square{5}
shape := []Shaper{a,b}//定义shape接口,将a,b以数组的形式放进去
fmt.Println(shape[0].Area(),shape[1].Area())//可用for-range读取每一个 计算值
}
//output:6 25
当然也可以用这样的方式来使用接口:
func main(){
a := &Rectangle{2,3}
var shape Shaper
shape = a
fmt.Println(shape.Area())
}
接口嵌套接口
type ReadWrite interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type Lock interface {
Lock()
Unlock()
}
type File interface {
ReadWrite
Lock
Close()
}
检测接口变量的类型
继续用上面求矩形面积的代码
a := &Rectangle{2,3}
var shape Shaper
shape = a //这里是Rectangle方法的接口
if v,ok := shape.(*Rectangle);ok{
fmt.Printf("The type of shape is %T\n",v)
}else{
fmt.Println("Shape does not have a variable type of Rectangle")
}
//output:The type of shape is *main.Rectangle
用type-switch判断接口类型
switch t := areaIntf.(type) {
case *Square:
fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:
fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:
fmt.Printf("nil value: nothing to check?\n")
default:
fmt.Printf("Unexpected type %T\n", t)
}
实用的空接口
可以将任何类型写进去,这里我以写入结构体为例:
package main
import "fmt"
type Person struct{
name string
age int
}
type Any interface{}
func main(){
var inter Any
per1 := new(Person)
per1.name="Mr_zwX"
per1.age=18
inter=per1
fmt.Println(inter)
}
//output:&{Mr_zwX 18}
复制数据切片到空接口切片(必须是显性复制的过程)
var dataSlice []myType = FuncReturnSlice()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for i, d := range dataSlice {
interfaceSlice[i] = d
}
通过反射修改值
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64=1.2345
v := reflect.ValueOf(x)
fmt.Println("Value:",v)//Value: 1.2345
fmt.Println("Settability:",v.CanSet())//Settability: false
v=reflect.ValueOf(&x)
fmt.Println("Type:",v.Type())//Type: *float64
fmt.Println("Settability:",v.CanSet())//Settability: false
v=v.Elem()
fmt.Println("Settability:",v.CanSet()) // Settability: true
v.SetFloat(2.3333)
fmt.Println(v)//2.3333
}