Trả lời lời chào cho nhiều người
Trong những thay đổi cuối cùng bạn sẽ thực hiện với mã của module, bạn sẽ thêm hỗ trợ để nhận lời chào cho nhiều người trong một yêu cầu. Nói cách khác, bạn sẽ xử lý đầu vào nhiều giá trị, rồi ghép các giá trị trong đầu vào đó với một đầu ra nhiều giá trị. Để làm điều này, bạn cần truyền một tập hợp tên vào một hàm có thể trả về lời chào cho mỗi tên trong số đó.
Tuy nhiên có một điểm cần lưu ý. Thay đổi tham số của hàm Hello
từ một tên đơn lẻ thành một tập hợp tên sẽ thay đổi chữ ký của hàm.
Nếu bạn đã publish module example.com/greetings
và người dùng đã viết mã gọi Hello, sự thay đổi đó
sẽ làm hỏng chương trình của họ.
Trong trường hợp này, lựa chọn tốt hơn là viết một hàm mới với tên khác. Hàm mới sẽ nhận nhiều tham số. Điều này bảo toàn hàm cũ để đảm bảo tính tương thích ngược.
-
Trong greetings/greetings.go, thay đổi mã của bạn để trông như sau.
package greetings import ( "errors" "fmt" "math/rand" ) // Hello returns a greeting for the named person. func Hello(name string) (string, error) { // If no name was given, return an error with a message. if name == "" { return name, errors.New("empty name") } // Create a message using a random format. message := fmt.Sprintf(randomFormat(), name) return message, nil } // Hellos returns a map that associates each of the named people // with a greeting message. func Hellos(names []string) (map[string]string, error) { // A map to associate names with messages. messages := make(map[string]string) // Loop through the received slice of names, calling // the Hello function to get a message for each name. for _, name := range names { message, err := Hello(name) if err != nil { return nil, err } // In the map, associate the retrieved message with // the name. messages[name] = message } return messages, nil } // randomFormat returns one of a set of greeting messages. The returned // message is selected at random. func randomFormat() string { // A slice of message formats. formats := []string{ "Hi, %v. Welcome!", "Great to see you, %v!", "Hail, %v! Well met!", } // Return one of the message formats selected at random. return formats[rand.Intn(len(formats))] }Trong đoạn mã này, bạn:
-
Thêm hàm
Helloscó tham số là một slice tên thay vì một tên đơn lẻ. Ngoài ra, bạn thay đổi một trong các kiểu trả về của nó từstringsangmapđể bạn có thể trả về tên được ánh xạ với các thông điệp lời chào. -
Cho hàm
Hellosmới gọi hàmHellohiện có. Điều này giúp giảm trùng lặp trong khi vẫn giữ cả hai hàm. -
Tạo một
messagesmap để liên kết mỗi tên nhận được (làm key) với một thông điệp được tạo ra (làm value). Trong Go, bạn khởi tạo một map với cú pháp sau:make(map[key-type]value-type). HàmHellostrả về map này cho người gọi. Để biết thêm về map, xem Go maps trong thực tế trên Go blog. -
Lặp qua các tên mà hàm nhận được, kiểm tra rằng mỗi tên có
giá trị không rỗng, rồi liên kết một thông điệp với mỗi tên. Trong vòng lặp
fornày,rangetrả về hai giá trị: chỉ số của phần tử hiện tại trong vòng lặp và bản sao của giá trị phần tử. Bạn không cần chỉ số, vì vậy bạn dùng định danh rỗng của Go (dấu gạch dưới) để bỏ qua nó. Để biết thêm, xem Định danh rỗng trong Effective Go.
-
Thêm hàm
-
Trong mã gọi hello/hello.go của bạn, truyền vào một slice tên, rồi in
nội dung của map tên/thông điệp bạn nhận về.
Trong hello.go, thay đổi mã của bạn để trông như sau.
package main import ( "fmt" "log" "example.com/greetings" ) func main() { // Set properties of the predefined Logger, including // the log entry prefix and a flag to disable printing // the time, source file, and line number. log.SetPrefix("greetings: ") log.SetFlags(0) // A slice of names. names := []string{"Gladys", "Samantha", "Darrin"} // Request greeting messages for the names. messages, err := greetings.Hellos(names) if err != nil { log.Fatal(err) } // If no error was returned, print the returned map of // messages to the console. fmt.Println(messages) }Với những thay đổi này, bạn:
-
Tạo biến
namescó kiểu slice chứa ba tên. -
Truyền biến
nameslàm đối số cho hàmHellos.
-
Tạo biến
-
Tại dòng lệnh, chuyển đến thư mục chứa hello/hello.go,
rồi dùng
go runđể xác nhận mã hoạt động.Đầu ra phải là biểu diễn chuỗi của map liên kết tên với thông điệp, giống như sau:
$ go run . map[Darrin:Hail, Darrin! Well met! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]
Phần này đã giới thiệu map để biểu diễn các cặp tên/giá trị. Nó cũng giới thiệu ý tưởng bảo toàn tính tương thích ngược bằng cách triển khai một hàm mới cho chức năng mới hoặc đã thay đổi trong một module. Để biết thêm về tính tương thích ngược, xem Giữ cho module của bạn tương thích.
Tiếp theo, bạn sẽ dùng các tính năng tích hợp của Go để tạo bài kiểm thử đơn vị cho mã của mình.