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 }