封装数据和行为
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.Age = 22
e2.Id = "2"
e2.Name = "Alice"
package encap
import (
"fmt"
"testing"
"unsafe"
)
type Employee struct {
Id string
Name string
Age int
}
func (e *Employee) String() string {
fmt.Printf("BBBAddress is %x\n", 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)
t.Log(e1)
t.Log(e1.Id)
t.Log(e2)
t.Logf("e is %T", e)
t.Logf("e2 is %T", e2)
}
func TestStructOperations(t *testing.T) {
e := Employee{"0", "Bob", 20}
fmt.Printf("AAAAddress is %x\n", unsafe.Pointer(&e.Name))
t.Log(e.String())
}
接口
- 接口为非入侵性,实现不依赖于接口定义
- 接口的定义可以包含在接口使用者包内
package interface_test
import "testing"
type Programmer interface {
WriteHelloWorld() string
}
type GoProgrammer struct{
}
func (g *GoProgrammer)WriteHelloWorld() string{
return "fmt.Println(\"Hello World\")"
}
func TestClient(t *testing.T) {
var p Programmer
p = new(GoProgrammer)
t.Log(p.WriteHelloWorld())
}
cannot use new(GoProgrammer) (type *GoProgrammer) as type Programmer in assignment:
*GoProgrammer does not implement Programmer (missing WriteHelloWorld method
接口变量
- 类型
- 数据
package customer_type
import (
"fmt"
"testing"
"time"
)
type IntConv func(op int) int
func timeSpent(inner IntConv) IntConv {
return func(n int) int {
start := time.Now()
ret := inner(n)
fmt.Println("time spent:", time.Since(start).Seconds())
return ret
}
}
func slowFun(op int) int {
time.Sleep(time.Second * 1)
return op
}
func TestFn(t *testing.T) {
tsSF := timeSpent(slowFun)
t.Log(tsSF(10))
}
扩展
面向对象扩展一般通过继承和复合来实现,Go不支持继承
package extension
import (
"fmt"
"testing"
)
type Pet struct {
}
func(p *Pet) Speak() {
fmt.Println("...")
}
func (p *Pet) SpeakTo(host string) {
p.Speak()
fmt.Println(" ", host )
}
type Dog struct {
p *Pet
}
func (d *Dog) Speak() {
fmt.Println(" dog speak")
}
func (d *Dog) SpeakTo(host string) {
d.p.SpeakTo(host)
}
func TestDog(t *testing.T) {
dog := new(Dog)
dog.SpeakTo("Andy")
}
多态
- 空接口可以表示任何类型
- 通过断言来将空接口转换为指定类型
v,ok := p.(int)//ok=true表示转换成功
package empty_interface
import (
"fmt"
"testing"
)
func DoSomething(p interface{}) {
// if i, ok := p.(int); ok {
// fmt.Println("Integer", i)
// return
// }
// if s, ok := p.(string); ok {
// fmt.Println("stirng", s)
// return
// }
// fmt.Println("Unknow Type")
switch v := p.(type) {
case int:
fmt.Println("Integer", v)
case string:
fmt.Println("String", v)
default:
fmt.Println("Unknow Type")
}
}
func TestEmptyInterfaceAssertion(t *testing.T) {
DoSomething(10)
DoSomething("10")
}