Go基础篇-"类"和接口

go语言中没有类的概念,它通过结构体来实现类的功能。

// user 类
type user struct {
    name       string
    email      string
}

// admin 类
type admin struct {
    // 自定义类
    person user
    // 内置类型
    level string
}

类的实例化

  // 1. 创建 user 变量,所有属性初始化为其零值
    var bill user
    fmt.Println(bill) // {  0 false}

    // 2. 创建 user 变量,并初始化属性值
    vix := user{
        name:       "vix",
        email:      "[email protected]",
    }
    fmt.Println(vix) // {vix [email protected]}
    // 直接使用属性值,属性值的顺序要与 struct 中定义的一致
    vix2 := user{"vix", "[email protected]"}
    fmt.Println(vix2) // {vix [email protected]}

    // 3. 含有自定义类型的 struct 进行初始化
   vix := admin{
        person: user{
            name:       "vix",
            email:      "[email protected]",
        },
        level: "super",
    }
    fmt.Println("vix:",vix) //vix: {{vix [email protected]} super}

方法
方法能给用户定义的类型添加行为。方法本身也是函数,只是在声明是在关键字和方法名之间添加一个参数(接受者)。

普通的函数定义 func 方法名(参数) 返回值{}
自定义类型的方法定义 func (接收者) 方法名(参数) 返回值{}
type user struct {
    name  string
    email string
}

// 普通的函数定义 "func 方法名(入参) 返回值"
// 自定义类型的函数定义 "func (接收者) 方法名(入参) 返回值"
// 值传递,拷贝一份 user
func (u user) notify() {
    fmt.Println("pass-by-value", u.name, u.email)
    u.email = "[email protected]"
}

// 传递指针(即地址),内部改变会影响外部
func (u *user) changeEmail(newEmail string) {
    // 不需要 (*u).email
    u.email = newEmail
}

func main() {
    // 1. user类型的值可以用来调用使用值接收者声明的方法
    bill := user{"bill", "[email protected]"}
    bill.notify() // {"bill", "[email protected]"}
    fmt.Println("1", bill.email) // "[email protected]"

    // 2. 指向 user 类型值的指针也可以用来调用使用值接收者声明的方法
    lisa := &user{"lisa", "[email protected]"}
    // 等价于 (*lisa).notify()
    // 注意:把 lisa 指针指向的 user 对象复制了一份,"再强调一次,notify 操作的是一个副本,只不过这次操作的是从 lisa 指针指向的值的副本。"
    lisa.notify() // {"lisa", "[email protected]"}
    fmt.Println("2", lisa.email) // "[email protected]"(错)  [email protected](对)

    // 3.user 类型的值可以用来调用使用指针接收者声明的方法
    // 等价于 (&bill).changeEmail ("[email protected]"),注意 changeEmail 接收的是一个指针
    bill.changeEmail("[email protected]")
    fmt.Println("3", bill.email) // "[email protected]"

    // 4.指向 user 类型值的指针可以用来调用使用指针接收者声明的方法
    lisa.changeEmail("[email protected]")
    fmt.Println("4", lisa.email) // "[email protected]"
}

接口

接口是用来定义行为的类型。这些行为是通过方法由用户定义的类型实现。
接口定义和实现

// notifier 是一个定义了通知类行为的接口
type notifier interface {
    // 接口方法
    notify()
}
# 实现
// notify 是使用值接收者实现 notifier interface 接口的方法, 对于值接收者,sendNotification(&u) 和 sendNotification(u) 都可
// sendNotification(&u) 和 sendNotification(u) 都可
func (u user) notify() {
    fmt.Println("notify", u)
}
// notify 是使用指针接收者实现 notifier interface 接口的方法,  对于指针接收者,只能使用 sendNotification(&u)
// 只能使用 sendNotification(&u)
func (u *user) notify() {
    fmt.Println("notify", *u)
}

持续更新~

你可能感兴趣的:(Go基础篇-"类"和接口)