Go语言是一种静态类型的编程语言,这意味着编译器需要在编译时知晓程序里每个值的类型。
值的类型给编译器提供两部分信息,一部分是需要分配多少内存,二部分表示这段内存表示什么。
int64类型的值需要8字节(64位),表示一个整数值。
float32类型的值需要4字节(32位),表示一个IEEE-754定义的二进制浮点数。
bool类型的值需要1字节(8位),表示布尔值true和false。
一、用户自定义类型
1、使用关键字struct
这个声明以关键字type开始,之后是新类型的名字,最后是关键字struct。
type user struct {
name string
email string
ext int
privileged 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 user
level 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 string
email string
}
//notify使用值接收者实现了一个方法
func (u user) notify() {
fmt.Printf("Sending User Email To %s<%s>\n"
u.name
u.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, ...) returnType
Method2(param2 type2, ...) returnType
...
}
例如:
type Shape interface {
Area() float32
Perimeter() float32
}
type Rectangle struct {
Width float32
Height 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、公开或未公开的标识符
首字母大写的变量可以被包外访问,即公开
首字母小写的变只能被包内访问,即不公开。