巫山做网站那家好,单页网站,网络规划设计师知识点,深圳网站设计的公司一、 duck typing duck typing意思是鸭子类型#xff0c;我们把具备鸭子的行为等部分特征的一个东西叫做鸭子#xff0c;这是鸭子类型的解释。其实#xff0c;在go语言中是采用鸭子类型这种思想来实现接口这种编程方式的#xff0c;我们把一个类只要实现了某接口的方法我们把具备鸭子的行为等部分特征的一个东西叫做鸭子这是鸭子类型的解释。其实在go语言中是采用鸭子类型这种思想来实现接口这种编程方式的我们把一个类只要实现了某接口的方法我们就说他是这个接口的实现类。如下 我们定义了一个接口 type duck interface { Get(s string) string //不用func修饰这个方法 } 下面写一个类type TheClass struct { S string } 这个类实现了上面接口中的方法如下并不需要声明我们要实现某个接口。func (tc TheClass) Get(s string) string { return tc.S; } 实现类前面的类型是属于值类型传递因为我们的接口里面实际是包了一个类型信息与及指针所以实现一般采用直接的值传递而不是指针传递因为一样可以对内容修改。 如上通过go语言的方式来说明了什么是鸭子类型。 二、 go语言中的接口。 上面讲过了接口的实现方式。 type duck interface { Get(s string) string } 之前我们有讲过两种go语言的两种“继承“方式一种是类似于装饰的叫做组合在类里面放”父类“另一种是取别名当然取别名算不上他不可以增加成员变量。那么接口可以”继承“吗?嗯当然可以如下 type littleDuck interface {duckA() string
} 这样应该叫接口的“继承” 刚刚在golang社区看到一篇被喷的文章下面有个人这样说“golang的接口是非入侵式的楼主让非得把**接口写入到**结构中真是人才啊“ 不是很理解什么意思难道不能够用接口继承吗问题先留在这里以后再解决。 n分钟过后 查了下什么叫入侵式与非入侵式附上自己的理解入侵式是指要申明接口实现了某一个接口什么的但是非入侵式就不用一般的oo语言例如java就是入侵式接口设计需要说明实现有层级但是go语言提倡是非入侵式相对入侵式可能更灵活一点不那么多依赖但是这两种设计都各有优点什么优点看完下面的就知道了接下来用例子来说下自己的理解吧。 à: Bird 接口 fly(),run(); Chicken 接口 run() Wild 接口 fly() 如上3个接口在入侵式接口设计中chicken接口与wild接口需要去继承bird接口因为他们属于这个大类那么我们创建一个chicken的实现类对象的话只需要实现chicken然后wild同理。这样做就是入侵式接口设计的思路。 在java中像这样 interface Bird{void run();void fly();
}interface Wild extends Bird{void run();
}interface Chicken extends Bird{void fly();
} 如果我们想要创建一个Wild的类型的类那么就需要创建一个需要给wild写个实现类一个Chicken类型的类就需要写一个Chicken实现类Bird就需要写一个Bird的实现类显然接口的复用性不高。当然这样的类型是相当清晰的。 同样有另外一种写法这样算是入侵式设计的思想如下 interface Run{void run();
}interface Fly{void fly();
} interface Bird1 extends Run,Fly{} java的接口继承是支持多继承的 这样的写法是一种组装的思想这也是oo语言中的入侵式接口设计思路通过继承的方式组装好然后去写Bird1的实现类没什么问题。 再看看非入侵式go语言推荐使用非入侵式接口设计在写实现类的时候不需要说明实现哪个接口也不需要去思考这是哪个接口的实现类只要实现相应的方法就行一般推荐这样写 type chicken interface {run()
} type wild interface {fly()
}type BirdImpl struct {
}func (b BirdImpl) run() {
}func (b BirdImpl) fly(){
} 如上的方式很灵活我们直接可以birdImpl创建一个类然后实现一个方法他就属于某一个类型不用去组装接口。当然我们也可以通过实现接口的方式来实现接口如 type Bird interface {run()fly()
}type chicken interface {run()
}type wild interface {fly()
} 这样的方式相当于bird实现了两个接口的接口我要创建实体对象的时候需要再创建一个类type BirdImpl struct {}func (b BirdImpl) run(){}func (b BirdImpl) fly(){} 这个类从这里看必定就实现了上述的3个接口这样的写法其实是可以的但是看起来冗余了许多我完全可以不需要Bird 或者另外两个接口。Go语言这样的接口设计方式相对更简单、灵活了。当然为了更具解释性我们可以把wild名改成Flychicken改成Run。当然这样的组合方式在go语言使用还是不少因为通过组合的方式也很方便灵活 那么我们可以这样来设计go语言的接口 type Bird interface {run()fly()
}type BirdImpl struct {}func (b BirdImpl) run() {}func (b BirdImpl) fly(){} 或者这样 type Run interface {run()
}type Fly interface {fly()
}type BirdImpl struct {}func (b BirdImpl) run() {}func (b BirdImpl) fly(){} 这样就是非入侵式接口设计不在接口使用继承。好像最后总结下爱就这么一句话不在接口关系中使用继承与及接口实现。 刚刚留了一个问题入侵式与非入侵式的比较从上面也可以看到入侵式接口设计类别层级什么的十分清晰没有那么多依赖解释性也比较好。非入侵式呢相对比较灵活简单接口复用率高。这都是我的理解哈不代表官方说法 网上对入侵式与非入侵式的观点很多以上只是我的理解而且go语言的源码里面也有很多组合接口的地方我也很难说这两个概念就先放一放。 三、 接口的使用。 首先说下接口变量的结构其内部有两个东西一个是接口实现者的类型一个是接口实现者的指针我们来看一段段代码 var o A o class.B{} fmt.Printf(%T,%p,o,o) 这里的B实现了接口AT是类型v是值可以知道o里面实际含有两个人东西。同时要提下如果在不同包下进行接口实现记住大写方法名首字母这样才是public的。 接下来我们讲下接口的组合上面讲到接口的组合不被推荐说法是有问题的通过后面的学习接口是可以被组合的而且在go的源码中还大量被用到这种组合的方式是很方便的当然存在的问题也是问题这个就不去争议了网上观点不一。 接口的组合上文已经讲过了这里我们来讲讲interface{}interface{}代表go语言里面的所有类型意义和java的Object一样但是go不是说所有类都继承interface没有这种说法 i : [...]interface{}{1,2,3,a,v} fmt.Println(i) 如上代码数组元素可以是任意类型当然可以作为函数传入值类型的时候就表示可以传入任意类型。 四、 Go两种常用接口。 a) stringer 这个接口相当与java的toString()方法我们只要实现string()string方法就算是实现了这个接口直接打印对象的时候自动调用string。 func (b B) String() string { return 实现了stringer的B } 比如这样写。 b) reader/writer file其实是实现了reader与writer两个接口的一般我们需要reader或者writer实例的时候可以传一个file进去也是一样的 这里可以用组合 type file interface{ Reader Writer } 转载于:https://www.cnblogs.com/luohuayu/p/9197894.html