Go语言中接口interface(多接口,空接口,类别开关)的应用
创始人
2024-03-21 10:46:54
0

接口是一组方法签名的集合,然后我们可以定义一个结构体struct来实现该接口的所有方法,这样来看,接口就定义了对象的行为。
对于接口大家都有着一定的了解,需要注意的就是实现接口,那就必须实现它里面的所有方法。

我们定义一个形状Shape的接口,里面声明了周长与面积的两个方法,然后定义矩形Rectangle与圆形Circular的结构体类型,通过这个类型实现这些方法,由于方法都已在接口里面声明,所以矩形与圆形的类型也就实现了形状Shape接口。

接口的实现

package mainimport ("fmt""math"
)// 形状接口,声明周长与面积方法
type Shape interface {Perimeter() float64Area() float64
}// 矩形结构体:宽度与高度
type Rectangle struct {Width  float64Height float64
}// 圆结构体:半径
type Circular struct {Radius float64
}// Rectangle实现周长的方法
func (R Rectangle) Perimeter() float64 {return (R.Width + R.Height) * 2
}// Rectangle实现面积的方法
func (R Rectangle) Area() float64 {return R.Width * R.Height
}// Circular实现周长的方法
func (C Circular) Perimeter() float64 {return math.Pi * (C.Radius * 2)
}// Circular实现面积的方法
func (C Circular) Area() float64 {return math.Pi * (C.Radius * C.Radius)
}
func main() {var shape Shape = Rectangle{4.5, 5}fmt.Printf("%T,%#v,%#v\n", shape, shape.Perimeter(), shape.Area()) //main.Rectangle,19,22.5var shape2 Shape = Circular{6}fmt.Printf("%T,%.2f,%.2f", shape2, shape2.Perimeter(), shape2.Area())//main.Circular,37.70,113.10
}

从结果也看出这个类型是可以赋值给接口,赋值的类型不一样,其接口类型也跟着发生变化。就是说什么类型的赋值,接口就会成为这个具体的类型。

参数是空接口

空接口也就是说里面没有声明方法,啥都没有,我们来看下空接口作为方法参数的一个例子:

package mainimport ("fmt"
)type GetInfo stringtype Person struct {Name stringAge  int
}// 空接口做参数
func test(i interface{}) {fmt.Printf("%T,%#v\n", i, i)
}
func main() {getinfo := GetInfo("寅恪光潜")person := Person{"Tony", 18}test(getinfo) //main.GetInfo,"寅恪光潜"test(person)  //main.Person,main.Person{Name:"Tony", Age:18}
}

我们可以看出test方法里面的参数是空接口,可以接收任意类型的参数,因为所有类型本已都实现了空接口。
结果也正确显示了参数进来的类型与值,再次证明了上面接口的类型也是随着具体类型变化而变化的。

多接口的实现

想要实现多接口,其实跟实现一个接口类似,只不过多个接口里的方法都一一实现,既然方法都已实现,这样也就实现了多接口。
我们定义两个形状接口,一个包含计算面积的方法,另一个包含计算体积的方法。然后我们分别将正方体类型赋值给这两个接口

package mainimport "fmt"type Shape1 interface {Area() float64
}
type Shape2 interface {Volume() float64
}// 正方体结构体:边长
type Cube struct {Edge float64
}// 面积
func (C Cube) Area() float64 {return 6 * C.Edge * C.Edge
}// 体积
func (C Cube) Volume() float64 {return C.Edge * C.Edge * C.Edge
}func main() {C := Cube{4}var S1 Shape1 = Cvar S2 Shape2 = Cfmt.Printf("%#v\n", S1.Area()) //96fmt.Printf("%#v", S2.Volume()) //64
}

因为正方体Cube实现了面积与体积的方法,也就是这两个接口里的方法都实现了,所以就实现了两个接口。
如果S1.Area() 换成 S1.Volume()会报错:

Build Error: go build -o c:\Users\Tony\__debug_bin.exe -gcflags all=-N -l .
# _/c_/Users/Tony
.\test.go:30:25: S1.Volume undefined (type Shape1 has no field or method Volume) (exit status 2)

因为这个S1接口里面是面积的方法,没有体积的方法,所以编译的时候就会报错。
那既然是实现了多接口,那想要调用另外接口的方法,该如何处理呢?
将用到类型的断言。类型断言的语法为:i.(Type)

func main() {var S1 Shape1 = Cube{4}c := S1.(Cube)fmt.Println(c.Area())   //96fmt.Println(c.Volume()) //64
}

这样就可以分别去调用两个接口里面的方法了。
当然了,这个类型是需要实现接口的,如果没有实现会报错,所以最好是有一种判断来处理。

s1, ok := S1.(Cube)
fmt.Println(s1, ok)//{4} true

通过这个ok值来判断,为true就是实现了这个接口。

type Tony interface {Sing() string
}
s2, ok2 := S1.(Tony)
fmt.Println(s2, ok2)// false

由于Cube没有实现Sing方法,也就是没有实现Tony接口,所以第二个返回值就是false

类型开关

通过上面的学习,我们又回到上面的空接口的示例,针对输入的类型分别做判断:

代码如下:

package mainimport ("fmt""strings"
)type Person struct {Name stringAge  int
}// 空接口参数
func test(i interface{}) {switch i.(type) {case string:fmt.Printf("%#v\n", strings.ToUpper(i.(string)))case int:fmt.Printf("%#v\n", i)default:fmt.Printf("%T,%v", i, i)}
}
func main() {person := Person{"Tony", 18}test("hello")test(110)test(person)
}
/*
"HELLO"
110
main.Person,{Tony 18}
*/

相关内容

热门资讯

Python|位运算|数组|动... 目录 1、只出现一次的数字(位运算,数组) 示例 选项代...
张岱的人物生平 张岱的人物生平张岱(414年-484年),字景山,吴郡吴县(今江苏苏州)人。南朝齐大臣。祖父张敞,东...
西游西后传演员女人物 西游西后传演员女人物西游西后传演员女人物 孙悟空 六小龄童 唐僧 徐少华 ...
名人故事中贾岛作诗内容简介 名人故事中贾岛作诗内容简介有一次,贾岛骑驴闯了官道.他正琢磨着一句诗,名叫《题李凝幽居》全诗如下:闲...
和男朋友一起优秀的文案? 和男朋友一起优秀的文案?1.希望是惟一所有的人都共同享有的好处;一无所有的人,仍拥有希望。2.生活,...
戴玉手镯的好处 戴玉手镯好还是... 戴玉手镯的好处 戴玉手镯好还是碧玺好 女人戴玉?戴玉好还是碧玺好点佩戴手镯,以和田玉手镯为佳!相嫌滑...
依然什么意思? 依然什么意思?依然(汉语词语)依然,汉语词汇。拼音:yī    rán基本解释:副词,指照往常、依旧...
高尔基的散文诗 高尔基的散文诗《海燕》、《大学》、《母亲》、《童年》这些都是比较出名的一些代表作。
心在飞扬作者简介 心在飞扬作者简介心在飞扬作者简介如下。根据相关公开资料查询,心在飞扬是一位优秀的小说作者,他的小说作...
卡什坦卡的故事赏析? 卡什坦卡的故事赏析?讲了一只小狗的故事, 我也是近来才读到这篇小说. 作家对动物的拟人描写真是惟妙...
林绍涛为简艾拿绿豆糕是哪一集 林绍涛为简艾拿绿豆糕是哪一集第三十二集。 贾宽认为是阎帅间接导致刘映霞住了院,第二天上班,他按捺不...
小爱同学是女生吗小安同学什么意... 小爱同学是女生吗小安同学什么意思 小爱同学,小安同学说你是女生。小安是男的。
内分泌失调导致脸上长斑,怎么调... 内分泌失调导致脸上长斑,怎么调理内分泌失调导致脸上长斑,怎么调理先调理内分泌,去看中医吧,另外用好的...
《魔幻仙境》刺客,骑士人物属性... 《魔幻仙境》刺客,骑士人物属性加点魔幻仙境骑士2功1体质
很喜欢她,该怎么办? 很喜欢她,该怎么办?太冷静了!! 太理智了!爱情是需要冲劲的~不要考虑着考虑那~否则缘...
言情小说作家 言情小说作家我比较喜欢匪我思存的,很虐,很悲,还有梅子黄时雨,笙离,叶萱,还有安宁的《温暖的玄》 小...
两个以名人的名字命名的风景名胜... 两个以名人的名字命名的风景名胜?快太白楼,李白。尚志公园,赵尚志。
幼儿教育的代表人物及其著作 幼儿教育的代表人物及其著作卡尔威特的《卡尔威特的教育》,小卡尔威特,他儿子成了天才后写的《小卡尔威特...
海贼王中为什么说路飞打凯多靠霸... 海贼王中为什么说路飞打凯多靠霸气升级?凯多是靠霸气升级吗?因为之前刚到时确实打不过人家因为路飞的实力...
运气不好拜财神有用吗运气不好拜... 运气不好拜财神有用吗运气不好拜财神有没有用1、运气不好拜财神有用。2、拜财神上香前先点蜡烛,照亮人神...