上一章节中介绍了在
Go中如何返回随机的问候语。在对模块代码进行的最后修改中,您将添加对在一个请求中获取多人问候的支持。换句话说,您将处理一个多值输入,然后将该输入中的值与一个多值输出配对。
如果直接修改greetings模块方法,则会影响到外部调用的模块hello。也即是第三方依赖你的代码会出现方法调用错误的情况,那么此时我们就不能直接修改原有方法,我们需要新增一个新的函数,可以理解为重载,便于当前代码向后做兼容。
代码编写
-
修改
greetings.go代码:package greetings import ( "errors" "fmt" "math/rand" "time" ) func Hello(name string) (string, error) { if name == "" { return name, errors.New("empty name") } message := fmt.Sprintf(randomFormat(), name) return message, nil } func Hellos(names []string) (map[string]string, error) { messages := make(map[string]string) for _, name := range names { message, err := Hello(name) if err != nil { return nil, err } messages[name] = message } return messages, nil } func init() { rand.Seed(time.Now().UnixNano()) } func randomFormat() string { formats := []string{ "Hi, %v. Welcome!", "Great to see you, %v!", "Hail, %v! Well met!", } return formats[rand.Intn(len(formats))] }以上代码有了以下修改部分:
- 添加一个
Hellos函数,它的参数是一个slice,而不是单个字符串参数。另外,您还将其返回类型从字符串更改为数组集合。 - 让新的
Hellos函数调用现有的Hello函数。这有助于减少重复,同时保留两个函数。 - 创建一个消息
map集合,将每个接收到的名称(作为键)与生成的消息(作为值)关联起来。在Go中,您使用以下语法初始化一个map: make(map[key-type]value-type)。Hellos函数将此映射返回给调用者。有关地图的更多信息,请参阅Go博客上的Go maps in action。 - 循环遍历函数收到的名称,检查每个名称都有一个非空值,然后将消息与每个名称关联起来。在这个
for循环中,range返回两个值:循环中当前项的索引和该项值。不需要索引进行关联,因此使用Go blank标识符(下划线)来忽略它。有关更多信息,请参见Effective Go中的空白标识符。
- 添加一个
-
修改
hello.go代码:package main import ( "fmt" "log" "montos.com/greetings" ) func main() { log.SetPrefix("greetings: ") log.SetFlags(0) names := []string{"Gladys", "Samantha", "Darrin"} messages, err := greetings.Hellos(names) if err != nil { log.Fatal(err) } fmt.Println(messages) }以上代码做了以下的一个改变:
- 创建一个
names变量作为一个包含三个名称的slice类型。 - 将
names变量作为参数传递给Hellos函数。
- 创建一个
-
运行以上修改过后的函数:
[root@montos-prod hello]# go run . map[Darrin:Great to see you, Darrin! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]
总结
上述中描述了我们如何在不破坏模块之间的依赖情况下,进行新增特性方法的调用。同时还介绍了除了
slice类型之外的map数据结构。