В последних изменениях, которые вы внесете в код своего модуля, вы добавите поддержку получения приветствия для нескольких человек в одном запросе. Другими словами, вы обрабатываете ввод с несколькими значениями, а затем объединяете значения в этом вводе с выводом с несколькими значениями. Для этого вам нужно передать набор имен функции, которая может возвращать приветствие для каждого из них.
Примечание. Этот раздел является частью руководства, состоящего из нескольких частей, которое начинается с создания модуля Go.
Но есть загвоздка. Изменение параметра функции Hello с одного имени на набор имен приведет к изменению сигнатуры функции. Если вы уже опубликовали модуль example.com/greetings, а пользователи уже написали код, вызывающий Hello, это изменение нарушит их программы.
В этой ситуации лучше написать новую функцию с другим именем. Новая функция примет несколько параметров. Это сохраняет старую функцию для обратной совместимости.
1. В greetings/greetings.go измените свой код так, чтобы он выглядел следующим образом.
package greetings
import (
"errors"
"fmt"
"math/rand"
"time"
)
// Hello возвращает приветствие для указанного человека.
func Hello(name string) (string, error) {
// Если имя не было указано, возвращаем ошибку с сообщением.
if name == "" {
return name, errors.New("empty name")
}
// Создаем сообщение в произвольном формате.
message := fmt.Sprintf(randomFormat(), name)
return message, nil
}
// Hellos возвращает карту,
// которая связывает каждого из названных людей
// с приветственным сообщением.
func Hellos(names []string) (map[string]string, error) {
// Карта для связывания имен с сообщениями.
messages := make(map[string]string)
// Перебираем полученный срез имен, вызываем
// функция Hello для получения сообщения для каждого имени.
for _, name := range names {
message, err := Hello(name)
if err != nil {
return nil, err
}
// В карте свяжите полученное сообщение с
// именем.
messages[name] = message
}
return messages, nil
}
// Init устанавливает начальные значения для переменных,
// используемых в функции.
func init() {
rand.Seed(time.Now().UnixNano())
}
// randomFormat возвращает одно
// из набора приветственных сообщений.
// Возвращаемое сообщение выбирается случайным образом.
func randomFormat() string {
// Срез форматов сообщений.
formats := []string{
"Hi, %v. Welcome!",
"Great to see you, %v!",
"Hail, %v! Well met!",
}
// Возвращаем один из случайно выбранных форматов сообщений.
return formats[rand.Intn(len(formats))]
}
В этом коде вы:
- Добавляете функцию Hellos, параметр которой представляет собой срез имен, а не одно имя. Кроме того, вы меняете один из возвращаемых им типов со строки на карту, чтобы вы могли возвращать имена, сопоставленные с приветственными сообщениями.
- Пусть новая функция Hellos вызовет существующую функцию Hello. Это помогает уменьшить дублирование, оставив при этом обе функции на своих местах.
- Создаете карту сообщений, чтобы связать каждое из полученных имен (как ключ) со сгенерированным сообщением (как значение). В Go вы инициализируете карту со следующим синтаксисом: make(map[key-type]value-type). У вас есть функция Hellos, возвращающая эту карту вызывающей стороне.
- Пройдете в цикле по именам, полученным вашей функцией, проверяя, что каждое из них имеет непустое значение, затем свяжете с каждым сообщение. В этом цикле for range возвращает два значения: индекс текущего элемента в цикле и копию значения элемента. Вам не нужен индекс, поэтому вы используете пустой идентификатор Go (подчеркивание), чтобы игнорировать его.
2. В коде вызова hello/hello.go передайте срез имен, а затем распечатайте содержимое карты имен/сообщений, которую вы получите.
В hello.go измените свой код так, чтобы он выглядел следующим образом.
package main
import (
"fmt"
"log"
"example.com/greetings"
)
func main() {
// Устанавливаем свойства предопределенного Logger,
// включая префикс записи журнала и флаг отключения печати
// времени, исходного файла и номера строки.
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 в качестве аргумента функции Hellos.
3. В командной строке перейдите в каталог, содержащий hello/hello.go, затем используйте команду go run, чтобы убедиться, что код работает.
Вывод должен быть строковым представлением карты, связывающей имена с сообщениями, примерно следующего вида:
$ go run .
map[Darrin:Hail, Darrin! Well met! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]
В этом посте представлены карты для представления пар имя/значение. Он также представил идею сохранения обратной совместимости путем реализации новой функции для новых или измененных функций в модуле.
Далее вы воспользуетесь встроенными функциями Go, чтобы создать модульный (юнит) тест для вашего кода.
Читайте также:
- Создание модуля в Golang
- Создание модуля в Golang: вызов своего кода из другого модуля
- Создание модуля в Golang: возврат и обработка ошибок
- Создание модуля в Golang: возврат случайного приветствия
- Создание модуля в Golang: добавить тест
- Создание модуля в Golang: скомпилируйте и установите приложение
Комментариев нет:
Отправить комментарий