一、结构体
结构体:由不同类型的元素组合而成。
1、struct结构体中的类型可以是任意类型;2、struct的存储空间连续的,其字段是按照声明时的顺序存放。
struct有两种形式:struct类型字面量,type定义的struct类型
struct{
FildName FiledType
FildName FiledType
FildName FiledType
}
自定义struct类型:
struct{
FildName FiledType
FildName FiledType
FildName FiledType
}
结构体初始化:
type Person struct {
Name string
Age int
}
type Student struct{
*Person
Number int
}
p := &Person{
Name: "Kris",
Age : 21,
}
s := Student {
Person: p,
Number : 110,
}
二、接口是一组方法的签名的集合。
接口定义方法名,而不是方法方法名是接口的组成部分,方法声明=方法名+方法签名
Golang中的接口,不需要显示的实现。Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量。
只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口
继承
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。
我们提到接口时,一般代指方法签名的接口,而空接口专门指代不带方法签名的接口。
接口的实现:
GO语言中,接口的实现是隐式的。即我们不用明确的指出某一个类型实现了某一个接口,只要在某一类型的方法中实现了接口中的全部方法签名,就意味着实现了这一接口。
Rectangle 和Triangle 都实现了Shape接口。
type Shape interface{
perimeter() float64
area() float64
}
type Rectangle struct{
a,b float64
}
func (r Rectangle)perimeter() float64{
return (r.a+r.b)*2
}
func (r Rectangle) area() float64{
return r.a*r.b
}
type Triangle struct{
a,b,c float64
}
func (t Triangle)perimeter() float64{
return t.a+t.b+t.c
}
func (t Triangle)area() float64 {
//海伦公式
p := t.perimeter()/2
return math.Sqrt(p*(p-t.a)*(p-t.b)*(p-t.c))
}
接口的动态调用:
当接口变量中存储了具体的动态类型时,可以调用接口中的所有方法。
var s Shape
s = Rectangle{3,4}
s.perimeter()
s.area()
s = Triangle(3,4,5)
fmt.Println("三角形周长:%v, 面积:%v", s.perimeter(), s.area())
一个类型可以实现多个接口。
例如:os.File 既实现了Reader接口,又实现了Writer接口。
//os.File 实现了一系列方法
type File interface{
*file
}
func (f *File) read(b []byte)(n int, err error){
n, e := fixcount(syscall.Read(f.fd,b))
...
return n,e
}
func (f *File) write(b []byte)(n int, err error){
...
return fixcount(syscall.Read(f.fd,b))
}
接口的定义还可以是其他接口的组合。
type ReadWriter interface{
Reader
Writer
}
type Reader interface{
Read (p []byte) (n int, err error)
}
type Writer interface{
Write (p []byte) (n int,err error)
}
接口类型的断言:语法:i.(type)在运行时获取接口中的类型。i代表接口。Type代表实现此接口的动态类型。