1、函数是⼀等公⺠
(1)可以有多个返回值
(2)所有参数都是值传递:slice,map,channel 会有传引⽤的错觉
(3)函数可以作为变量的值
(4)函数可以作为参数和返回值
package fn_test
import (
"fmt"
"math/rand"
"testing"
"time"
)
func returnMultiValues() (int, int) {
// 多返回值
return rand.Intn(10), rand.Intn(20)
}
func timeSpent(inner func(op int) int) func(op int) int {
//函数参数和函数返回值
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) {
// 可忽略不需要值
a, _ := returnMultiValues()
t.Log(a)
tsSF := timeSpent(slowFun)
t.Log(tsSF(10))
}
func Sum(ops ...int) int {
// 可变参数数量
ret := 0
for _, op := range ops {
ret += op
}
return ret
}
func TestVarParam(t *testing.T) {
t.Log(Sum(1, 2, 3, 4))
t.Log(Sum(1, 2, 3, 4, 5))
}
func Clear() {
fmt.Println("Clear resources.")
}
func TestDefer(t *testing.T) {
// defer在panic后执行
defer Clear()
fmt.Println("Start")
panic("err")
}
2、面向对象编程
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))
}
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) String() string {
fmt.Printf("Address 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("Address 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())
}
package extension
import (
"fmt"
"testing"
)
type Pet struct {
}
func (p *Pet) Speak() {
fmt.Print("...")
}
func (p *Pet) SpeakTo(host string) {
p.Speak()
fmt.Println(" ", host)
}
// 匿名嵌套
type Dog struct {
Pet
}
func (d *Dog) Speak() {
fmt.Print("Wang!")
}
func TestDog(t *testing.T) {
dog := new(Dog)
dog.SpeakTo("Chao")
}
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")
}
package polymorphism
import (
"fmt"
"testing"
)
type Code string
type Programmer interface {
WriteHelloWorld() Code
}
type GoProgrammer struct {
}
func (p *GoProgrammer) WriteHelloWorld() Code {
return "fmt.Println(\"Hello World!\")"
}
type JavaProgrammer struct {
}
func (p *JavaProgrammer) WriteHelloWorld() Code {
return "System.out.Println(\"Hello World!\")"
}
func writeFirstProgram(p Programmer) {
fmt.Printf("%T %v\n", p, p.WriteHelloWorld())
}
func TestPolymorphism(t *testing.T) {
// 多态
goProg := &GoProgrammer{}
javaProg := new(JavaProgrammer)
writeFirstProgram(goProg)
writeFirstProgram(javaProg)
}