3typeShow struct{
4s string
5}
6func(this *Show)Show(){
7fmt.Println( "This is another Demo: ",this.s)
8}
接下来我们可以在main.go中使用这个接口和对应的方法:
1//main.go
2packagemain
3import(
4"show"
5"demo"
6"demo2"
7)
8funcmain(){
9vards show.Shower = &demo.Show{ "string from main"}
10vard2s show.Shower = &demo2.Show{ "string from main"}
11ds.Show()
12}
我们一般用一个函数来包装参数,使之直接返回一个接口类型。这是interface warp function的其中一种用法:
1//demo/demo.go
2funcNewShow(s string)show.Shower{ return&Show{s}}
3//demo.Show不是Shower接口的实现类型,*demo.Show才是
在main.go中使用这个方法来创建接口:
1//main.go
2ds := demo.NewShow( "string from main")
3ds.Show()
注意在写interface warp的时候返回类型必须是接口类型,即func NewShow(s string) Show {return &Show{s}} 或func NewShow(s string) *Show {return &Show{s}} 都是错误的。虽说他们或许可以成功执行ds.Show() 操作,但他们都只是一个结构体,也就是执行ds.(show.Shower) 类型断言时编译器会抛出错误。
以上都是很基础的部分。接下来我们考虑一个需求,即我们需要用一个方法(接口)来实现将字符串连续打印多遍的功能。例如在stl中LimitedReader 的实现方法。为此,我们创建一个结构体ShowMultiTimes并继承Shower:
1//which package does it belong??
2typeShowMutliTimes_s struct{
3n int//n times
4}
5func(this *ShowMultiTimes_s)Show(){
6fori:= 0;i<this.n;i++{
7//??
8}
9}
可以发现,这个方法应该同时对所有Shower的实现类型生效。同时他打印的内容也与Shower的实现类型(如Demo,Demo2)有关,因此他应该是一个属于package show的方法:
1packageshow
2import"fmt"
3
4typeShowMultiTimes struct{
5S Shower
6n int
7}
8func(this *ShowMultiTimes)Show(){
9fori:= 0;i<this.n;i++{
10fmt.Print( "Time",i, ": ")
11this.S.Show()
12}
13}
我们说interface wrapper function的第二种用法,即接受interface类型参数,并返回与其参数类型相同的返回值。
1funcShowNTimes(s Shower, n int)Shower{ return&ShowMultiTimes{s,n}}
ShowNTimes是一个wrapper function,它在s的外面再包裹上ShowMultiTimes。通过wrapper function将NewShow和ShowMultiTimes 的两者巧妙的组合在了一起。这样当我们采用包装后的Shower去Read时,输出的是经过处理后的字符串了。
1//main.go
2packagemain
3import(
4"show"
5"demo"
6"demo2"
7)
8funcmain(){
9st:=show.ShowNTimes(test.NewShowI( "String from main"), 3)
10st.Show()
11}
可以看到,interface warp function可以组合成一个chain,因为其wrapper function返回值类型与parameter类型相同。
ID:Golangweb