Go基础——包管理和接口

12.包

一个包可以简单理解为一个存放.go文件的文件夹。 该文件夹下面的所有go文件都要在代码的第一行添加如下代码,声明该文件归属的包。

  • 一个文件夹下面直接包含的文件只能归属一个package,同样一个package的文件不能在多个文件夹下。
  • 包名可以不和文件夹的名字一样,包名不能包含 - 符号。
  • 包名为main的包为应用程序的入口包,这种包编译后会得到一个可执行文件,而编译不包含main包的源代码则不会得到可执行文件。

变量名首字母为大写则,它是共有的,对外可见

12.1不在同一个项目下

src
   |_demo
	   |_main
	        |_main.go
	        |_go.mod
	   |_calc
	        |_add.go
	        |_sub.go
	        |_go.mod

(img-VRI5sCuD-1633784979646)(go1.assets/image-20211008154240852.png)]

12.2在同一目录下

src
   |_pkgdemo
	   |_main.go
	   |_calc
	        |_add.go
	        |_go.mod

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vEOiYC9R-1633784979650)(go1.assets/image-20211008160801849.png)]

12.3init执行顺序

init函数是一个无参无返回值的函数在这里插入图片描述

13.接口

接口(interface)是一种类型,一种抽象的类型。

interface是一组method的集合。接口做的事就像是定义一个规则,只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性,只关心行为(方法)。

当看到一个接口类型的值时,不知道它是什么,唯一知道的是通过它的方法能做什么。

13.1定义

type 接口类型名 interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2}

13.2实现接口条件

接口就是一个需要实现的方法列表

只要全部实现了接口中的方法,那么就实现了这个接口。

// 定义接口
type sayer interface {
	say()
}

定义结构体

//定义man结构体
type man struct{
	name string
}
// 定义woman结构体
type woman struct{
	name string
	age int8
}

因为sayer接口里面有say方法, 所以要给man woman分别实现say方法

// say方法,man
func (m man) say(){
	fmt.Println("man say ...", m.name)
}
// say方法, woman
func (w woman) say(){
	fmt.Println("woman say ...", w.name)
}

完整代码

//定义man结构体
type man struct{
	name string
}
// 定义woman结构体
type woman struct{
	name string
	age int8
}

// 定义接口
type sayer interface {
	say()
}
// say方法,man
func (m man) say(){
	fmt.Println("man say ...", m.name)
}
// say方法, woman
func (w woman) say(){
	fmt.Println("woman say ...", w.name)
}
// beat打
func beat (arg sayer){
	arg.say()
}

func main(){
	var m1 = man{name: "小芳"}
	beat(m1)
	var w1 = woman{name:"大黄", age: 18}
	beat(w1)
}

13.3值接受者,指针接受者

13.3.1值接受者

//定义man结构体
type man struct{
	name string
}
// say方法,man
func (m man) say(){
	fmt.Println("man say ...", m.name)
}
var m1 = man{name: "小芳"}
beat(m1)

值接收者实现接口之后,不管是man结构体还是结构体指针*man类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖,man指针m1内部会自动求值*m1

13.3.2指针接受者

//定义man结构体
type man struct{
	name string
}
// say方法,man
func (m *man) say(){
	fmt.Println("man say ...", m.name)
}
var m1 = &man{name: "小芳"}
beat(m1)

13.4类型与接口关系

  • 一个类型可以实现多个接口
// sayer接口
type sayer interface{
    say()
}
//runner接口
type runer interface{
    run()
}
//定义dog结构体
type dog struct{}
// dog实现sayer接口
func (d dog) say(){
    fmt.Println("dog say...")
}
// dog实现runner接口
func (d dog) run(){
    fmt.Println("dog run...")
}
func main(){
    var x sayer
    var y runer
    
    var a = dog{}
    x = a
    y = a
    x.say()
    y.run()
}
  • 多个类型可以实现一个接口

    // sayer接口
    type sayer interface{
        say()
    }
    
    //定义dog结构体
    type dog struct{}
    //定义cat结构体
    type cat struct{}
    
    func (d dog)say(){
    	fmt.Println("dog say...")
    }
    // cat实现say()
    func (c cat)say(){
    	fmt.Println("cat say...")
    }
    

    一个接口的方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。

// WashingMachine 洗衣机接口
type WashingMachine interface {
	wash()
	dry()
}

// 甩干器
type dryer struct{}

// 实现WashingMachine接口的dry()方法
func (d dryer) dry() {
	fmt.Println("甩干器")
}

// 海尔洗衣机
type haier struct {
	dryer //嵌入甩干器
}

// 实现WashingMachine接口的wash()方法
func (h haier) wash() {
	fmt.Println("洗衣机")
}

13.5接口嵌套

// Speaker 接口
type Speaker interface {
	say()
}

// Runner 接口
type Runner interface {
	move()
}

// 接口嵌套,得到动物接口,能说能动的就是动物
type animal interface {
	Speaker
	Runner
}

13.6空接口

空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

空接口类型的变量可以存储任意类型的变量。

var x interface{}
y := "xiaosheng"
x = y
z := 18
x = z
c := make(map[string]int, 16)
x = c
//空接口作为函数参数
func test(t interface{}){
    
}
//用空接口实现可以保存任意类型的字典
var dic = make(map[string]interface{})

13.7断言

一个接口的值(简称接口值)是由一个具体类型具体类型的值两部分组成的。这两部分分别称为接口的动态类型动态值

想获取一个接口里面的值可以用断言

x.(type)
var x int
v, ok = x.(int)
func main() {
	var x interface{}
	x = "Hello"
	v, ok := x.(string)
	if ok {
		fmt.Println(v)
	} else {
		fmt.Println("类型断言失败")
	}
}
func justifyType(x interface{}) {
	switch v := x.(type) {
	case string:
		fmt.Printf("type of x is string,value is %v\n", v)
	case int:
		fmt.Printf("type of x is int is %v\n", v)
	case bool:
		fmt.Printf("type of x is bool is %v\n", v)
	default:
		fmt.Println("error ")
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值