go语言--方法与接口

本文探讨了Go语言中的方法和接口。方法定义需要先定义结构体,可通过结构体.方法名调用,指针接收者能避免拷贝提高效率。接口是方法签名的集合,接口变量可保存实现接口的任何类型值,体现了多态性。Go语言的接口实现是隐式的,不需要显示声明,并且可以作为函数参数和返回值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法

1.方法的定义

go语言中定义方法,首先需要定义结构体struct,然后就可以为结构题愉快的定义方法了。

package main

import (
	"fmt"
)

type People struct{
	age int
	name string
}

// People的sayName方法
func (people People) sayName(){
	fmt.Println(people.name)
}

func main() {
	man := People{18, "kinlonli"}
	woman := People{20, "zhangshan"}
	man.sayName()
	woman.sayName()
}

2.方法和函数的区别与联系

其实方法就是函数,他们都是为了定义一组操作的封装体。不过方法的是面向对象的,它与结构直接关联,可以直接通过结构体(java中的对象)直接调用,以 结构体.方法名 进行调用,具更高的封装性。

3.指针接收者(指针方法)

指针接收者在调用方法时候,调用前后是使用同一份内存的数据的,不会进行拷贝操作。因此频繁调用某个方法时,可以考虑使用指针,可以提升效率。

package main

import (
	"fmt"
)

type People struct{
	age int
	name string
}

// 只需要将People类型 -> *People类型
func (people *People) change(){
	people.age = 30
	people.name = "zhangsan"
}

func main() {
	man := People{18, "kinlonli"}
	fmt.Println(man)
	man.change()
	fmt.Println(man)
}

[Running] go run "/Users/lijinlong/local/go/GoProjects/go_demo/main.go"
{18 kinlonli}
{30 zhangsan}

调用change函数之后,man的数据被修改了。函数传递参数时,没有对people具体内容进行拷贝,拷贝的仅仅是指针变量,因此函数体操作会对people内容进行修改。
可以尝试将*People -> People,会发现前后数据没有改变。

4.方法与指针的重定向

方法中允许指针和值之间相互转化,会隐式的将指针自动转为值,或者将值转为指针。

指针转为值

package main

import (
	"fmt"
)

type People struct{
	age int
	name string
}

func (people People) sayName(){
	fmt.Println(people.name)
}

func main() {
	man := People{18, "kinlonli"}
	man.sayName()
	p := &man
	// 会自动将p.sayName() -> (*p).sayName()
	p.sayName()
}

值转为指针

package main

import (
	"fmt"
)

type People struct{
	age int
	name string
}

func (people *People) sayName(){
	fmt.Println(people.name)
}

func main() {
	man := People{18, "kinlonli"}
	// 会自动将man.sayName() -> (&man).sayName()
	man.sayName()
	p := &man
	p.sayName()
}

在方法中允许这样隐式的转换,但是函数可不允许这样的转换,在函数中依旧要严格按照参数类型匹配传递参数,否则会变异不通过。

参考:
方法与指针重定向
方法与指针重定向(续)

接口

1.接口的定义

接口是一组方法签名的定义,接口变量可以保存实现了该接口方法一系列的值。
例如:

type Things inteface {
     sayName()
     getAge() int8
}

2. 接口的使用

接口值可以为任一实现了接口的结构体,不同类型的结构体调用相同的接口方法时展现出不同的行为,体现了多态性。比如以下代码中,Student和Teacher都实现了People这个接口,接口People可以为Student或Teacher类型的值或者对应的指针,他们调用sayName()方法时表现出了不一样的行为。

package main

import (
	"fmt"
)

type People interface {
	sayName()
	getAge() int8
}

type Student struct{
	name string
	age int8
}

// Student结构体实现People接口内的方法
func (student *Student) sayName() {
	fmt.Println("my name is " + student.name)
}

func (student *Student) getAge() int8{
	return student.age
}

type Teacher struct {
	name string
	age int8
	subject string
}

// Teacher结构体实现People接口内的方法
func (teacher *Teacher) sayName(){
	fmt.Println("I'm " + teacher.subject + " teacher " + teacher.name)
}

func (teacher *Teacher) getAge() int8{
	return teacher.age
}

func main() {
	// 接口变量接受学生指针
	var people1 People = &Student{name : "kinlonli", age : 18}
	// 使用接口调用学生对应的方法
	people1.sayName()
	fmt.Println(people1.getAge())

	// 接口变量接收老师的指针
	var people2 People = &Teacher{name : "xiaoyue", age : 28, subject : "math"}
	// 使用接口调用老师对应的方法
	people2.sayName()
	fmt.Println(people2.getAge())
}

[Running] go run "/Users/lijinlong/local/go/GoProjects/go_demo/main.go"
my name is kinlonli
18
I'm math teacher xiaoyue
28

3.接口的特点

  • 实现是隐性的
  • 接口即是值
  • 空接口

第一,在go语言中接口的实现不需要像java一样显示的使用 implements 关键字显示的实现,解耦了接口定义
,接口定义可以出现在任何包中。
第二,接口就是明确的一个值,他也想函数一样作为函数的参数或者返回值。
第三,空接口就是 interface{} ,任何变量都可以赋值给空接口变量,因为任何变量都至少实现了0个方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值