> 文章列表 > 五、Go语言的类型系统

五、Go语言的类型系统

五、Go语言的类型系统

Go语言是一种静态类型的编程语言,这意味着编译器需要在编译时知晓程序里每个值的类型。
值的类型给编译器提供两部分信息,一部分是需要分配多少内存,二部分表示这段内存表示什么。
int64类型的值需要8字节(64位),表示一个整数值。
float32类型的值需要4字节(32位),表示一个IEEE-754定义的二进制浮点数。
bool类型的值需要1字节(8位),表示布尔值true和false。

一、用户自定义类型
1、使用关键字struct
这个声明以关键字type开始,之后是新类型的名字,最后是关键字struct。

type user struct {name stringemail stringext intprivileged bool
}

2、使用结构类型声明变量,并初始化为其零值
这个声明以关键字type开始,之后是新类型的名字,最后是关键字struct。

var bill user

3、使用结构字面量来声明一个结构类型的变量

lisa := user {name:    "Lisa",email:   "lisa@email.com"ext:     123,privileged: true,
}

4、不使用字段名,创建结构类型的值

lisa := user{"Lisa", "lisa@email.com", 123, true};

5、结构套结构

type admin struct{person userlevel string
}

6、使用结构字面量来创建字段的值

fred := admin{person:user{name:  "Lisa",email: "lisa@email.com",ext:    123,privileged: true,},level: "super",
}

7、基于int64声明一个新类型
基于一个已有的类型将其作为新类型的类型说明

type Duration int64

二、方法
方法能给用户定义的类型添加新的行为。实际上也是函数,只是在声明时,在关键字func和方法名之间增加了一个参数。

func (接收者类型) 方法名(参数列表) (返回值列表) {函数体
}
package main
import ("fmt"
)type user struct {name stringemail string
}//notify使用值接收者实现了一个方法
func (u user) notify() {fmt.Printf("Sending User Email To %s<%s>\\n"u.nameu.email)
}
//changeEmail使用指针接受者实现了一个方法
func (u *user) changeEmail(email string) {u.email = email
}
//
func main() {bill := user{"Bill", "bill@email.com"}bill.notify()lisa := &user{"Lisa", "lisa@email.com"}lisa.notify()bill.changeEmail("bill@newdomain.com")bill.notify()
}

三、类型的本质
1、内置类型
数值类型、字符串类型和布尔类型
2、引用类型
GO语言的引用类型有如下几个:切片、映射、通道、接口和函数类型
当声明上述类型的变量时,创建的变量被称为标头值。从技术上说,字符串也是一种引用类型,每个引用类型创建的标头值时包含一个指向底层数据结构的指针。每个引用类型还包含一组独特的字段,用于管理底层数据结构。因为标头值是为复制而设计的,所以永远不需要共享一个引用类型的值。标头值里包含一个指针,因此通过复制来传递一个引用类型的值的副本,本质上就是在共享底层数据结构。
3、结构类型
4、接口
Golang接口定义了一组方法签名,如果某个类型实现了接口的所有方法,则认为该类型实现了该接口,接口使得类型和接口解耦,可以灵活定义与使用。
接口定义格式为:

type InterfaceName interface{Method1(param1 type1, ...) returnTypeMethod2(param2 type2, ...) returnType...
}

例如:

type Shape interface {Area() float32Perimeter() float32 
}type Rectangle struct {Width  float32Height float32 
}func (r Rectangle) Area() float32 {return r.Width * r.Height
}func (r Rectangle) Perimeter() float32 {return 2*(r.Width + r.Height)
}type Circle struct {Radius float32 
}func (c Circle) Area() float32 {return c.Radius * c.Radius * 3.14 
}func (c Circle) Perimeter() float32 {return 2 * 3.14 * c.Radius  
}

然后我们可以定义一个方法,接收Shape接口作为参数,调用接口中的方法:

func printInfo(s Shape) {fmt.Println("Area:", s.Area())fmt.Println("Perimeter:", s.Perimeter())
}

在main函数中,我们可以调用printInfo()方法并传入Rectangle或Circle类型的参数:

func main() {r := Rectangle{10.0, 20.0} printInfo(r)c := Circle{10}printInfo(c)  
}

5、嵌入类型
即一个结构内部可以声明另一个结构体

6、公开或未公开的标识符
首字母大写的变量可以被包外访问,即公开
首字母小写的变只能被包内访问,即不公开。