15丨行为的定义和实现

面向对象编程

封装数据和行为

结构体定义

type Employee struct {
 Id string
 Name string
 Age int
}

实例创建及初始化

e := Employee{"0", "Bob", 20}
e1 := Employee{Name: "Mike", Age: 30}
e2 := new(Employee) //注意这⾥返回的引⽤/指针,相当于 e := &Employee{}
e2.Id = “2" //与其他主要编程语⾔的差异:通过实例的指针访问成员不需要使⽤->
e2.Age = 22
e2.Name = “Rose"

 

 

行为(方法)定义

与其他主要编程语言的差异

 

 

测试代码

package encap

import (
    "fmt"
    "testing"
    "unsafe"
)

type Employee struct {
    Id   string
    Name string
    Age  int
}

func (e *Employee) String() string {
    fmt.Printf("Address is %x", unsafe.Pointer(&e.Name))
    return fmt.Sprintf("ID:%s/Name:%s/Age:%d", e.Id, e.Name, e.Age)
}

func (e Employee) StringCopy() string { // 更大的开销
    fmt.Printf("Address is %x", unsafe.Pointer(&e.Name)) // 实例的值被调用,会被复制一份
    return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
}

func TestCreateEmployeeObj(t *testing.T) {
    e := Employee{"0", "Bob", 20} //
    e1 := Employee{Name: "Mike", Age: 30}
    e2 := new(Employee) //返回的是指针
    e2.Id = "2"
    e2.Age = 22
    e2.Name = "Rose"
    t.Log(e)               //{0 Bob 20}
    t.Log(e1)              //{ Mike 30}
    t.Log(e1.Id)           // 为空
    t.Log(e2)              //因为e2反回的是指针,这里触发的是指针方法  Address is c00006a520    encap_test.go:35: ID:2/Name:Rose/Age:22
    t.Logf("e is %T", e)   // e is encap.Employee
    t.Logf("e2 is %T", e2) //e2 is *encap.Employee // 指针类型
}

func TestStructOperations(t *testing.T) {
    e := Employee{"0", "Bob", 20}
    fmt.Printf("origin Address is %x\n", unsafe.Pointer(&e.Name)) //Address is c00006a520
    t.Log("指针方法", e.String())                                     // 调用实例的方法 Address is c00006a520    encap_test.go:43: 指针方法 ID:0/Name:Bob/Age:20
    t.Log("内存拷贝", e.StringCopy())                                 // Address is c00006a550    encap_test.go:44: 内存拷贝 ID:0-Name:Bob-Age:20
}

 

posted @ 2021-01-22 22:26  元贞  阅读(166)  评论(0编辑  收藏  举报