Golang结构体中的接口类型变量说明

先看下面的代码:

package main

import "fmt"

// 首先定义两个接口 TestInt1 和 TestInt2

// TestInt1 is an interface
type TestInt1 interface {
	func1()
	func2()
	func3()
}

// TestInt2 is an interface
type TestInt2 interface {
	func4()
	func5()
	func6()
}

// TestStruct1 is a struct
type TestStruct1 struct {
	TestInt1
	str string
}

// TestStruct2 is a struct
type TestStruct2 struct {
	TestInt2
	str string
}

// TestStruct3 is a struct
type TestStruct3 struct {
	TestInt1
	TestInt2
	str string
}

// 定义一个结构体,并实现TestInt1和TestInt2接口
type emptyCtx struct {
	a string
	b string
}

func (e *emptyCtx) func1() {
	fmt.Println("func1: " + e.a)
}

func (e *emptyCtx) func2() {
	fmt.Println("func2: " + e.b)
}

func (e *emptyCtx) func3() {
	fmt.Println("func3: " + e.a + " " + e.b)
}

func (e *emptyCtx) func4() {
	fmt.Println("func4: " + e.a)
}

func (e *emptyCtx) func5() {
	fmt.Println("func5: " + e.b)
}

func (e *emptyCtx) func6() {
	fmt.Println("func6: " + e.a + " " + e.b)
}

func newStruct1(i1 TestInt1) *TestStruct1 {
	return &TestStruct1{
		TestInt1: i1,
		str:      "newStruct1",
	}
}

func newStruct2(i2 TestInt2) *TestStruct2 {
	return &TestStruct2{
		TestInt2: i2,
		str:      "newStruct2",
	}
}

func newStruct3(i1 TestInt1, i2 TestInt2) *TestStruct3 {
	return &TestStruct3{
		TestInt1: i1,
		TestInt2: i2,
		str:      "newStruct3",
	}
}

func newStruct1ReturnTestInt1(i1 TestInt1) TestInt1 {
	return &TestStruct1{
		TestInt1: i1,
		str:      "newStruct1ReturnTestInt1",
	}
}

func newStruct2ReturnTestInt2(i2 TestInt2) TestInt2 {
	return &TestStruct2{
		TestInt2: i2,
		str:      "newStruct2ReturnTestInt2",
	}
}

func newStruct3ReturnTestInt1(i1 TestInt1, i2 TestInt2) TestInt1 {
	return &TestStruct3{
		TestInt1: i1,
		TestInt2: i2,
		str:      "newStruct3ReturnTestInt1",
	}
}

func newStruct3ReturnTestInt2(i1 TestInt1, i2 TestInt2) TestInt2 {
	return &TestStruct3{
		TestInt1: i1,
		TestInt2: i2,
		str:      "newStruct3ReturnTestInt2",
	}
}

func newStruct3ReturnEmptyInterface(i1 TestInt1, i2 TestInt2) interface{} {
	return &TestStruct3{
		TestInt1: i1,
		TestInt2: i2,
		str:      "newStruct3ReturnTestInt2",
	}
}

func main() {

	ex := &emptyCtx{
		a: "aaa",
		b: "bbb",
	}

	fmt.Printf("ex: %v, address: %p\n", ex, ex)

	ns1 := newStruct1(ex)
	ns2 := newStruct2(ex)
	ns3 := newStruct3(ex, ex)

	fmt.Printf("ns1: %v, address: %p\n", ns1, ns1)
	fmt.Printf("ns2: %v, address: %p\n", ns2, ns2)
	fmt.Printf("ns3: %v, address: %p\n", ns3, ns3)

	s1ri1 := newStruct1ReturnTestInt1(ex)
	s2ri2 := newStruct2ReturnTestInt2(ex)

	fmt.Printf("s1ri1: %v, address: %p\n", s1ri1, s1ri1)
	fmt.Printf("s2ri2: %v, address: %p\n", s2ri2, s2ri2)

	s3ri1 := newStruct3ReturnTestInt1(ex, ex)
	s3ri2 := newStruct3ReturnTestInt2(ex, ex)

	fmt.Printf("s3ri1: %v, address: %p\n", s3ri1, s3ri1)
	fmt.Printf("s3ri2: %v, address: %p\n", s3ri2, s3ri2)

	s3rei := newStruct3ReturnEmptyInterface(ex, ex)

	// 将空接口转换成TestInt1接口
	if intf, ok := s3rei.(TestInt1); ok {

		intf.func1()
		intf.func2()
		intf.func3()
	}

	// 将空接口转换成TestInt2接口
	if intf, ok := s3rei.(TestInt2); ok {

		intf.func4()
		intf.func5()
		intf.func6()
	}
}

上面代码中emptyCtx实现了两个接口。其他的每个结构体内都包含了接口类型的属性,所以实例化结构体的时候可以返回对应的接口类型,具体参看上面几个返回接口类型的函数。但是这个地方需要注意,结构体中的接口类型属性不能有具体的变量名称,否则编译器会提示该变量没有实现接口的方法,导致返回接口类型的函数产生语法错误。

TestStruct3包含了两个接口类型的属性,所以实际上可以返回两个接口类型。这里返回了一个空接口,在后面的处理中可以根据具体需求转换成不同的接口类型。

这种返回接口类型实例的做法,实际上屏蔽了结构体的其他属性和方法,只能调用接口方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值