go中的结构体--struct

go中的结构体–struct

go中没有面向对象语言中类的概念,go中的struct结构体实现了类似于类的功能,包括类似于成员函数,成员变量等功能

1.go中结构体的定义

1.1 值类型

type T struct {
	a int 
}

// 通过以下方式,定义了一个T类型的t变量,为值类型
var t T 

1.2 引用类型

type T struct {
	a int 
}

// 通过以下方式,定义了一个&T类型的t变量,为引用类型
// 使用new函数,是为t变量分配了内存空间,在go中,引用类型要使用,必须先分配空间
var t = new(T)

2.go中结构体的内存分布

在go中,结构体在内存中是以连续块的方式存放的
在这里插入图片描述

3.结构体中的匿名字段

结构体中,不带变量,只有类型的属性,为结构体中的匿名字段

type T struct {
	// 像这种只有类型,没有对应变量的,被称为结构体中的匿名字段
	int 
}

3.1 匿名字段的定义和使用

  1. 匿名字段为非结构体类型,可以直接通过t.int这样的方式赋值和使用该匿名字段,因为是根据类型直接使用的,所以一个结构体只能有一个该类型的匿名字段
  2. 匿名字段为结构体类型,可以通过outer.a这种方式直接访问到inner中的属性和方法
type Inner1 struct {
	a int 
	b int 
}

type Outer struct {
	c int 
	int 
	Inner1
}

var o Outer 

o.c = 100
// 可以直接通过以下方式使用Outer中的int匿名字段
o.int = 1000
// 可以通过以下方式访问Inner中的属性
o.a = 100

3.2 命名冲突问题

type Inner1 struct {
	a int 
	b int 
}

type Inner2 struct {
	a int 
	c int 
}

type Outer struct {
	b int 
	Inner1
	Inner2
}

var o Outer

1.上述例子中,当Outer和Inner1中有相同的属性b,此时o.b为外层Outer的b属性;即当外层和内层发生冲突时,优先选择外层
2.上述例子中,当Inner1和Inner2中有相同的属性a,且Outer中没有属性a,此时o.a这种方式使用会报错,因为无法知道要定位到具体哪个Inner中

4.方法

go中没有类似于java中的成员变量和成员方法,可以通过接受者的方式来定义该结构体的对应方法

type T struct {
}

func (t *T) test() {
}

通过以上方式,通过接收者来定义该结构体的对应方法

4.1 该结构体和其对应的方法必须在同一个包内

对于go中自定义的类型,是不能在其他包内直接定义其方法的,可以使用类型别名或者匿名字段的方法

package main 

// 这种方式是错误的,方法和结构体必须在同一个包内
func (t time.Time) test() {
	
}

// 使用类型别名
type T time.Time 

func (t T) test1() {
	t1 := time.Time(t)
	// 使用类型别名的方式后,需强制类型转换才能使用原来类型的方法
	t1.Minute()
}

// 使用匿名字段
type T1 struct{
	time.Time
}

func (t *T1) test2() {
	// 使用匿名字段后,可直接通过下列方式使用原来类型的方法
	t.Minute()
}

4.2 定义方法时,接收者可为值类型或者引用类型

1.接收者为值类型时,不会改变原来的值

type T struct{
	a int
}

func (t T) NotChange() {
	t.a = 100
}

var t T
t.a = 10
t.NotChange() // 执行该函数后,t.a仍然为10,不会改变原来的值

2.接收者为引用类型时,会改变原来的值

type T struct{
	a int
}

func (t *T) Change() {
	t.a = 100
}

var t T 
t.a = 10 
t.Change() // 执行该函数后,t.a的值会更改为100,会改变原来的值

3.在go中,无论是值类型还是引用类型,在方法或函数中,都是采用值传递的。对于引用类型来说,传递的是地址的拷贝,因此引用类型会改变指向的地址的内容

4.3 可通过匿名字段的方式实现类似于java中的继承效果

type Inner1 struct{	
}

type Inner2 struct{
}

func (i Inner1) call() {
	fmt.Println("calling")
}

func (i Inner2) take() {
	fmt.Println("taking")
}

type Outer struct {
	Inner1 
	Inner2
}

var o Outer
// 通过以下方式可以达到类似于继承的效果
o.call()
o.take()

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang ,可以使用 strconv 包的函数将 int 类型转换为 string 类型,也可以使用 fmt.Sprintf() 函数将 int 类型格式化为 string 类型。同样,也可以将 string 类型转换为 int 类型。 以下是一个示例代码,演示了如何在嵌套的结构体将 int 类型转换为 string 类型: ```go package main import ( "fmt" "strconv" ) type Person struct { Name string Age int } type Company struct { Name string Employee Person FoundedAt int } func (p Person) String() string { return fmt.Sprintf("%v (%v years)", p.Name, p.Age) } func (c Company) String() string { return fmt.Sprintf("%v, founded in %v, employee: %v", c.Name, c.FoundedAt, c.Employee) } func main() { p := Person{"John", 30} c := Company{"Golang Inc.", p, 2009} // 将 int 类型转换为 string 类型 c.FoundedAt = 2010 fmt.Println(c) // Golang Inc., founded in 2010, employee: John (30 years) // 将 string 类型转换为 int 类型 foundedAt, err := strconv.Atoi("2009") if err != nil { fmt.Println(err) } c.FoundedAt = foundedAt fmt.Println(c) // Golang Inc., founded in 2009, employee: John (30 years) } ``` 在上面的示例代码,我们定义了两个结构体:Person 和 Company。Company 结构体包含一个 Person 类型的嵌套结构体 Employee 和一个 int 类型的字段 FoundedAt。 在 Person 结构体,我们定义了一个 String() 方法,用于将结构体格式化为字符串。 在 Company 结构体,我们也定义了一个 String() 方法,用于将结构体格式化为字符串。在该方法,我们使用 fmt.Sprintf() 函数将 Employee 结构体格式化为字符串,并将 int 类型的 FoundedAt 字段转换为 string 类型。 在 main() 函数,我们创建了一个 Person 类型的变量 p 和一个 Company 类型的变量 c,其 c 的 Employee 字段为 p。我们使用 fmt.Println() 函数将 c 变量打印出来,以检查它的 Employee 和 FoundedAt 字段是否已正确转换为 string 类型或 int 类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值