fmt这个包,有个String的接口,如果实现了,就会调用,然后进行格式化。实现了接口,就可以自定义输出。在调用实现了这个接口的类,就会自动调用string进行格式化。
比如instance这个结构体实现了String,在fmt.Println() 时候,就会自动调用String这个接口,去格式化。
//实现String接口
func (p *Instance) String() string {
return p.host + ":" + strconv.Itoa(p.port)
}
对比两次输出:
#//实现String() 之前
PS F:\go\src\go_dev\day6\homework> go run .\work02\main\main.go
[0xc0000044c0 0xc0000044e0 0xc000004500 0xc000004540 0xc000004560 0xc000004580 0xc0000045a0 0xc0000045c0 0xc0000045e0 0xc000004600]
&{192.168.119.151 8080}
&{192.168.42.59 8080}
&{192.168.96.155 8080}
&{192.168.96.155 8080}
#//实现String() 之后
PS F:\go\src\go_dev\day6\homework> go run .\work02\main\main.go
[192.168.86.132:8080 192.168.122.254:8080 192.168.151.153:8080 192.168.115.155:8080 192.168.61.150:8080 192.168.119.151:8080 192.168.42.59:8080 192.168.88.239:8080 192.168.96.155:8080 192.168.167.131:8080]
192.168.119.151:8080
192.168.42.59:8080
192.168.96.155:8080
学会通过配置文件或者传入的参数动态调整函数的实现方式,比如是用随机还是轮询调度方法,如果传入不支持的参数,就恢复默认值。有点像支付渠道。
如果要换一种调度算法,就需要改代码,如下:
func main() {
//[<nil> ... <nil> 0xc0000044c0...0xc0000045e0] 会出现10个nil
//insts := make([]*balance.Instance, 10)
var insts []*balance.Instance
for i := 0; i < 10; i++ {
host := fmt.Sprintf("192.168.%d.%d", rand.Intn(255), rand.Intn(255))
one := balance.NewInstance(host, 8080)
insts = append(insts, one)
}
fmt.Println(insts)
//balancer := &balance.RandomBalance{}
balancer := &balance.RandomRobinBalance{}
for {
//inst, err := balancer.DoBalance(insts)
inst, err := balancer.DoBalance(insts)
if err != nil {
fmt.Println("do balance rr err:", err)
continue
}
fmt.Println(inst)
time.Sleep(1 * time.Second)
}
}
怎么才能不该代码呢?添加if/switch 分支,并制定默认的参数,可以通过改配置文件或者传入的参数,实现函数不一样的输出结果。
package main
import (
"fmt"
"go_dev/day6/homework/work02/balance"
"math/rand"
"os"
"time"
)
func main() {
//[<nil> ... <nil> 0xc0000044c0...0xc0000045e0] 会出现10个nil
//insts := make([]*balance.Instance, 10)
var insts []*balance.Instance
for i := 0; i < 10; i++ {
host := fmt.Sprintf("192.168.%d.%d", rand.Intn(255), rand.Intn(255))
one := balance.NewInstance(host, 8080)
insts = append(insts, one)
}
//fmt.Println(insts)
var balancer balance.Balancer
//默认是random
var conf = "random"
//如果有输入参数,就选择输入的参数,os.Args代表用户输入参数
if len(os.Args) > 1 {
conf = os.Args[1]
}
switch conf {
case "random":
balancer = &balance.RandomBalance{}
fmt.Println("use RandomBalance balancer")
case "randomrobin":
balancer = &balance.RandomRobinBalance{}
fmt.Println("use RandomRobinBalance balancer")
default:
fmt.Println("balancer support “random/randomrobin” ,use default random balancer")
balancer = &balance.RandomBalance{}
fmt.Println("use RandomBalance balance")
}
//balancer := &balance.RandomBalance{}
//balancer := &balance.RandomRobinBalance{}
for {
//inst, err := balancer.DoBalance(insts)
inst, err := balancer.DoBalance(insts)
if err != nil {
fmt.Println("do balance rr err:", err)
continue
}
fmt.Println(inst)
time.Sleep(1 * time.Second)
}
}
运行结果:(默认/ 制定参数/ 乱传入参数)
#默认参数
PS F:\go\src\go_dev\day6\homework> go run .\work02\main\main.go
use RandomBalance balance
192.168.119.151:8080
192.168.42.59:8080
192.168.96.155:8080
192.168.96.155:8080
exit status 2
#传入有效参数
PS F:\go\src\go_dev\day6\homework> go run .\work02\main\main.go randomrobin
use RandomRobinBalance balance
192.168.86.132:8080
192.168.122.254:8080
192.168.151.153:8080
exit status 2
#胡乱传参,就给出提示,并恢复默认值
PS F:\go\src\go_dev\day6\homework> go run .\work02\main\main.go xxxx
now support random/randomrobin,use default random balancer
use RandomBalance balance
192.168.119.151:8080
192.168.42.59:8080
192.168.96.155:8080
exit status 2
PS F:\go\src\go_dev\day6\homework>
但是上面的balance,只实现了两个调度算法,需要添加支持用户自定义的算法,这样怎么实现呢?可以通过添加一个调度算法管理的模块,对系统提供的,自定义的调度算法进行管理。并且动态地添加支持。明天继续学习。