Go 语言的介面(interface)是一组以方法签名(method signatures)的组合,透过介面来定义物件的一组行为,它将物件导向的内容组织,实现得非常方便。
Interface 定义了一组 method,Interface 里的值可以保存实现这些方法的任何值 。这里以 Go Tutorial 上的例子来解说,这边有稍微做了些调整,我们直接看以下的程序码:
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs() float64
}
func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f // a MyFloat implements Abser
fmt.Println(a.Abs())
a = &v // a *Vertex implements Abser
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)
}
我们来解释一下上述程序码, Abser interface 实现了 Abs method,而 Abs method 同时定义在 Vertex struct 和 MyFloat 上。
Interface 里到底能存什麽值呢?如果我们定义了一个 interface 的变数,那麽这个变数可以实现该 interface 里所有的变数型态。例如上述的例子, Abser interface 最终实现了 Vertex struct 和 MyFloat 两种变数型态,而最後储存 float64 这个变数型态。
我们再来看一个例子:
package main
import (
"fmt"
"math"
)
type I interface {
M()
}
type T struct {
S string
}
func (t *T) M() {
fmt.Println(t.S)
}
type F float64
func (f F) M() {
fmt.Println(f)
}
func main() {
var i I
i = &T{"Hello"}
describe(i)
i.M()
i = F(math.Pi)
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("(%v, %T)\n", i, i)
}
Interface I 实现了 M method,而 M method 定义在 T struct 和 F float64上,最後 M method 因出了两个型态变数中带的参数
空 interface 不包含任何的 method,所以所有的型别都实现了空 interface。空 interface 对於描述起不到任何的作用(因为它不包含任何的 method),但是在我们需要储存任意型别的数值时,空 interface 及发挥到他的作用,因为它可以储存任意变数型态,我们来看一下下面的例子:
package main
import (
"fmt"
)
var a interface{}
func main() {
// 定义 a 为空介面
var i int = 5
s := "Hello world"
// a 可以储存任意型别的数值
a = i
fmt.Println(a) // 5
a = s
fmt.Println(a) // Hello world
}
一个 nil interface 值既不包含值也不包含具体类型。
在 nil interface 上调用方法是一个运行时错误,因为 interface 里没有任何类型定义在任何方法上。
package main
import "fmt"
type I interface {
M()
}
func main() {
var i I
describe(i)
i.M()
}
func describe(i I) {
fmt.Printf("(%v, %T)\n", i, i)
}
今天带来 Go 语言中非常巧妙的设计 interface,它让物件导向,内容组织实现非常的方便,本人自觉 Go 语言的 interface 简单且非常实用,希望今天带来的文章对你有初步认识 interface 的帮助,谢谢你今天的阅读。
https://tour.golang.org/methods/9
https://tour.golang.org/methods/10
https://tour.golang.org/methods/11
https://tour.golang.org/methods/12
https://tour.golang.org/methods/13
https://tour.golang.org/methods/14
>>: 33岁转职者的前端笔记-DAY 23 JavaScript 变数与型别
YAML YAML的诞生不算太晚, 1.0在2004就出了, 虽然晚了JSON 5年(1999年),...
前言 在 上一篇 内容中,我提到了「渐进式总结(progressive summary)」的写笔记技...
点击进入React源码调试仓库。 React在构建用户界面整体遵循函数式的编程理念,即固定的输入有固...
【前言】 本系列为个人前端学习之路的学习笔记,在过往的学习过程中累积了很多笔记,如今想藉着IT邦帮忙...
slot 在子元件(内层)中预留空间,由父元件(外层)设定、分配内容。 子元件本身对slot无控制权...