go语言学习第四天==》结构体、引用、匿名组合、接口、any类型

go语言学习第四天==》结构体、引用、匿名组合、接口、any类型

- 类型
基础类型,如byte int bool float等
复合类型 如数组,结构体,指针
可以指向任意对象的类型(any类型)
值语义和引用语义
面向对象,即所有具备面向对象特征(比如成员方法)的类型
接口

为类型添加方法
Go中,可以给任意类型(包括内置类型,但是不包括指针类型)
添加相应的方法

type Integer int 
 
func (a Integer) Less(b Integer) bool {     
	return a < b 
}
//使用
var a Interger=1
b:=a.less(2) 

可以传入指针

func (a *Integer) Add(b Integer) {     
	*a += b 
}

func main() {     
	var a Integer = 1     
	a.Add(2)         
	fmt.Println("a =", a) 
}
//结果为3

如果不传指针

func (a Integer) Add(b Integer) {     
	a += b 
}
//结果为1

引用

//非引用↓
var a = [3]int{1, 2, 3} 
var b = a
b[1]++ 
fmt.Println(a, b)
//结果[123],[133]

/引用
var a = [3]int{1, 2, 3} 
var b = &a
b[1]++ 
fmt.Println(a, *b)
//结果[133],[133]


结构体
demo

//定义结构体
type Rect struct {     
	x, y float64     
	width, height float64 
}
//定义一个成员方法计算面积
func (r *Rect) Area() float64 {     
	return r.width * r.height 
} 

//在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,
//如bool零值false,int零值为0,string零值为空字符串。 
//所以创建实列对象可以这样:
rect1 := new(Rect) 
rect2 := &Rect{} 
rect3 := &Rect{0, 0, 100, 200} 
rect4 := &Rect{width: 100, height: 200} 

///
匿名组合
go也提供继承,但是采用组合的文法,称为匿名组合

type Base struct {     
	Name string 
} 
//再给它两个成员方法
func (base *Base) Foo() { ... } 
func (base *Base) Bar() { ... } 

这样来“继承”Base

type Foo struct {    
	Base     ... 
} 
 
func (foo *Foo) Bar() {     
	foo.Base.Bar()     ... 
} 

还可以以指针方式派生

type Foo struct {     
	*Base     ...
 } 

//
可见性
要使某个符号对其他包可见,需将该符号定义为大写字母开头如

type Rect struct {     
	X, Y float64     
	Width, Height float64 
}

如小写,就只能在该类型所在的包内使用
如以下成员方法

func (r *Rect) area() float64 {     
	return r.Width * r.Height 
}

- 接口
接口在go中非常重要
///
非侵入式接口
注意:
go中结构体只要有该接口的所有要求函数,
则这个结构体就实现了该接口
demo

//定义File结构体
type File struct {  
// ... 
} 
func (f *File) Read(buf []byte) (n int, err error) 
func (f *File) Write(buf []byte) (n int, err error) 
func (f *File) Seek(off int64, whence int) (pos int64, err error) 
func (f *File) Close() error 

//现有如下接口
type IFile interface {     
	Read(buf []byte) (n int, err error)    
	Write(buf []byte) (n int, err error)     
	Seek(off int64, whence int) (pos int64, err error)     
	Close() error 
} 
 
type IReader interface {     
	Read(buf []byte) (n int, err error) 
} 
 
type IWriter interface {     
	Write(buf []byte) (n int, err error) 
} 
 
type ICloser interface {     
	Close() error 
}

//File结构体并没有从这些接口继承,甚至不知道这些接口的存在,
//但是都实现了这些接口
//所以可以赋值

var file1 IFile = new(File) 
var file2 IReader = new(File) 
var file3 IWriter = new(File) 
var file4 ICloser = new(File)

///
接口赋值
将对象实列赋值给接口

//有一个类型
type Integer int 
func (a Integer) Less(b Integer) bool {     
	return a < b 
} 
func (a *Integer) Add(b Integer) {     //有指针
	*a += b 
}
//接口
type LessAdder interface {     
	Less(b Integer) bool     
	Add(b Integer) 				//无指针
}
把Interger对象实列赋值给LessAdder接口
var a Integer = 1 
var b LessAdder = &a  //关键   A
/*
由于 A行
go语言根据下面的函数
func (a Integer) Less(b Integer) bool
自动生成
func (a *Integer) Less(b Integer) bool {     
	return (*a).Less(b) 
} 
这样类型*Interger就既存在less()方法,又存在add()方法 符合接口LessAdder

但是  无法  根据func (a *Integer) Add(b Integer)
自动生成
func (a Integer) Add(b Integer) {     
	(&a).Add(b) //关键行B
}
因为(&a).Add()改变的只是函数参数a,对外部实际要操作的对象并无影响,这不符合用 户的预期。
*/

//
将接口赋值给另一种接口
只要接口A的方法列表示接口B的方法列表子集,B就可以赋值给A,
方法列表相同可以相互赋值(列表顺序可以不同)


接口查询

demo
如果file1指向的对象实列实现了two.IStream接口,则ok=true

var file1 Writer = ... 
if file5, ok := file1.(two.IStream); ok {     
... 

} 

///
类型查询
变量名.(type)

v1:="im a boss" 
v := v1.(type) 
//fmt.Println(v) 结果为string 

///
接口组合
把方法组合起来

// ReadWriter接口将基本的Read和Write方法组合起来 
type ReadWriter interface {     
	Read(p []byte) (n int, err error)     
	Write(p []byte) (n int, err error) 
} 

/
any类型
go语言中任何对象实列都满足空接口interface[] 所以

var v1 interface{} = 1       // 将int类型赋值给interface{} 
var v2 interface{} = "abc"   // 将string类型赋值给interface{} 
var v3 interface{} = &v2     // 将*interface{}类型赋值给interface{} 
var v4 interface{} = struct{ X int }{1} 
var v5 interface{} = &struct{ X int }{1} 

当函数可以接受任意的对象实例时,我们会将其声明为interface{}

func Printf(fmt string, args ...interface{}) 
func Println(args ...interface{}) 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值