定义Struct
//定义类型
//首字母大写则在其他包中可见,否则只能在当前包中使用
type Point struct {
x, y float64
}
//声明变量
p := Point{} //用零值初始化
p0 := new(Point)//和上面的一样
var p1 Point = Point{3,4} // 值
var p2 Point = Point{x:1}// 指定字段名来初始化值,x==3,y==0
var p2 *Point = &Point{3,4} // 返回指针
//如果省略字段的名字,可以创建匿名字段,例如:
//匿名字段一般用于嵌入另一个类型,以实现组合和委派
//a的变量可以直接访问T1、T2、T3的方法
type a struct{
T1 //字段名字是 T1
*T2 //字段名字是 T2
P.T3 //字段名字是 T3
x,y int //字段名字是 x 和 y
}
Struct方法
//方法名前面加上Struct名称来标记该函数是Point的方法
//当使用值类型来定义时,会复制一个新的对象
//因此在方法里对struct的修改不会影响到方法外的对象
func (self Point) Length() float {
//该方法中不会对外部的Point产生影响
return math.Sqrt(self.x*self.x + self.y*self.y);
}
//使用指针类型来定义方法
//方法中的Point是指针,因此方法中会影响外部的Point
func (self *Point) Scale(factor float64) {
self.x = self.x * factor
self.y = self.y * factor
}
定义接口
对于只有一个方法的接口通常用方法名+er的方式来命名
type Abser interface {
Abs() float64
}
实现接口
Go无需像java那样显式的声明implement了哪个接口,任何实现了接口全部方法的类型就相当于实现了该接口
//实现接口的可以是任何类型,比如:
//自定义一个float类型,并实现接口
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
//定义一个struct并实现接口
type Vertex struct {
X, Y float64
}
//注意用指针定义方法时与上个例子的区别:
//*Vertex 实现了接口Abser,但Vertex就没有实现接口
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
需要特别指出的很重要的一点就是所有的对象都实现了这个空接口
interface {}
因此可以定义接受任何类型的变量
func g(obj interface{}) int{
return obj.(I).Get()//把obj转换成I类型的接口
}
运行时判断类型
//(type)只能在switch中使用
switch i := x.(type) {
case nil:
printString("x is nil")
case int:
printInt(i) // i is an int
case float64:
printFloat64(i) // i is a float64
case func(int) float64:
printFunction(i) // i is a function
case bool, string:
printString("type is bool or string") // i is an interface{}
default:
printString("don't know the type")
}
//另一种等价的写法
v := x // x is evaluated exactly once
if v == nil {
printString("x is nil")
} else if i, isInt := v.(int); isInt {
printInt(i) // i is an int
} else if i, isFloat64 := v.(float64); isFloat64 {
printFloat64(i) // i is a float64
} else if i, isFunc := v.(func(int) float64); isFunc {
printFunction(i) // i is a function
} else {
i1, isBool := v.(bool)
i2, isString := v.(string)
if isBool || isString {
i := v
printString("type is bool or string") // i is an interface{}
} else {
i := v
printString("don't know the type") // i is an interface{}
}
}
//当然也可以判断接口变量实际是哪种类型
if t,ok:=I.(Abser);ok {
//如果I的实际类型是Abser,则ok为true
//并把I转换成Abser赋给t
}
//如果可以肯定I就是Abser就可以简单地写
t := I.(Abser)