【Go学习笔记】6 -- 类型系统 -- Struct

类型系统是一个语言的类型体系结构,一个典型的类包含以下内容

基础类型: 如byte,int, bool等
复合类型: 如数组,结构体,指针等
可以只想任意对象的类型
值和引用语义
面向对象
接口

Go语言中的大多数类型都是值语义,并且都可以包含对应的操作。
你可以给任何类型 增加 方法。
在实现接口是,不需要从该接口继承,只需要实现该接口要求的所有方法就可以了。
任意类型都可以被 Any 类型引用。Any类型就是空接口 即 interface()

值语义和引用语义

二者的区别在于赋值,如:

b = a
b.Modify()

# 如果 b 的修改不会影 a ,这个类型就属于 值类型, 如果会影响 a ,这个类型就是引用类型
# Go 语言中的大多数类型都是 值语义 ,包括 基本类型,复合类型,最典型的就是 数组。

Go语言中有4个类型比较特别,看起来像引用语义,但是这不影响我们将 Go语言类型看成 值语义

数组切片:
map
channel: (goroutine)间的同学设施
接口(interface)

# 这几种类型都使用了指针,

结构体 (struct类型)

Go 语言的结构体放弃了很多的对象特征,只保留了组合(composition)这个最基本的特征。

// 声明很简单,如下,包含了两个属性,一个string,一个int
tpye person struct {
    name string
	age int
}

// 使用办法
var P person           // P 现在就是struct类型的变量

P.name = "Any"
P.age = 20
fmt.Printf("The Person's name is %s",P.name)

# 这种P的声明,还可以用其他方式,如b
按顺序提供初始化值
P := person("fitch",24)
通过 fields:value 方式声明,这种声明,可以任意顺序
P := person(age:24, name:"fitch")
使用new ,这里 P 的类型是person
P := new(person)

struct 匿名函数

Go 支持只提供类型,不谢字段名的方式。这种方式称为匿名字段,也称为嵌入字段。
当匿名字段是一个struct的时候,这个struct所拥有的全部字段被隐式的引入了。

package main
import "fmt"

tpye Human struct{
    name string
	age string
	weight int
}

type Student struct{
    // 这里的Human 就是匿名函数
	Human
	tech string
}
func main(){
    // 初始化
	mark := Student(Human("Tom",20,120), "Computer Science"
	
	// 访问相应字段  Human有的字段,全部被Student所引入
	fmt.Printf("HIs name is: %s", mark.name)
	fmt。Printf("His age is: %s", mark.age)
	fmt.Printf("His weight is: %s", mark.weight)
	fmt.Printf("His tech is: %s", mark.tech)
	
	// modify tech info
	mark.tech = "AI"
	fmt.Printf("Tom changed his tech")
	fmt.Printf("Tom's tech is:%s", mark.tech)
	
	// modify weight info
	fmt.Printf("Tom is not an athlet anymore")
	mark.weight += 60
	fmt.Printf("Tom's weight is: %s", mark.weight)
}

# Student 还可以访问 Human 这个字段作为字段名称
mark.Human = Human("Fitch", 23, 150)
mark.Human.age -= 1

通过匿名访问和修改字段是很有用的,当然,不只是struct 字段,其实,所有的内置函数和自定义类型都是可以作为匿名字段的。

package main
import "fmt"

// 自定义类型
type sKills []string

type Human struct{
    name string
	age int
	weight int
}

type Student struct{
    Human
	// 自定义类型
	sKills
	// 内置函数
	int
	tech string
}

func main(){
    fitch := Student(Human("Fitch", 34, 170), "Jave")
	// 访问相应字段  
	fmt.Printf("HIs name is: %s", fitch.name)
	fmt。Printf("His age is: %s", fitch.age)
	fmt.Printf("His weight is: %s", fitch.weight)
	fmt.Printf("His tech is: %s", fitch.tech)
	
	// modify sKills
	fitch.sKills = []string{"antomy"}
	fmt.Printf("His sKills is: %s", fitch.sKills )
	fmt。Printf("Fitch acquired tow new ones")
	fitch.sKills = append(fitch.sKills, "Go", "Python")
	fmt.Printf("Fitch's sKills is: %s", fitch.sKills)
	
	// modify int
	fitch.int = 3
	fmt。Printf("Fitch's preferred number = %d", fitch.int)
}

上面两个匿名函数的调用,所用包含的字段都是不同的,如果几个函数都包含了同一个字段,要如何处理呢

// 如 上例中的 Human Student 都包含了Address 如何访问呢
// Go 的设定是最外层优先,如果你通过Student.Address 访问的时候,访问的是Student里的,不是Human里的。
// 如果要访问Human里的,要用: Student.Human.Address

fmt。Printf("Fitch's Address is: %s", fitch.Address)
// 访问Human里的字段
fmt.Printf("Fitch's Address is: %s", fitch.Human.Address)

其他示例

# 官方示例
// An empty struct.
struct {} // 空结构体

// A struct with 6 fields. // 6个域 包括 空域
struct {
	x, y int // 定义了两个域 x、y,类型都是int,这就是 IdentifierList 了
	u float32
	_ float32  // padding // 空域,下划线
	A *[]int // 定义一个 名称为 A 的 整形数组的指针
	F func() // 定义一个 名称为 F 的 函数类型 域——无参数、无返回类型
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值