<!--{
    "Title": "Return greetings for multiple people",
    "Path":  "/doc/tutorial/greetings-multiple-people"
}-->

<p>
  In the last changes you'll make to your module's code, you'll add support for
  getting greetings for multiple people in one request. In other words, you'll
  handle a multiple-value input and pair values with a multiple-value output.
</p>

<aside class="Note">
  <strong>Note:</strong> This topic is part of a multi-part tutorial that begins
  with <a href="create-module.html">Create a Go module</a>.
</aside>

<p>
  To do this, you'll need to pass a set of names to a function that can return a
  greeting for each of them. Changing the <code>Hello</code> function's
  parameter from a single name to a set of names would change the function
  signature. If you had already published the <code>greetings</code> module and
  users had already written code calling <code>Hello</code>, that change would
  break their programs. In this situation, a better choice is to give new
  functionality a new name.
</p>

<p>
  In the last code you'll add with this tutorial, update the code as if you've
  already published a version of the <code>greetings</code> module. Instead of
  changing the <code>Hello</code> function, add a new function
  <code>Hellos</code> that takes a set of names. Then, for the sake of
  simplicity, have the new function call the existing one. Keeping both
  functions in the package leaves the original for existing callers (or future
  callers who only need one greeting) and adds a new one for callers that want
  the expanded functionality.
</p>

<ol>
  <li>
    In greetings/greetings.go, change your code so it looks like the following.

    <pre>
package greetings

import (
    "errors"
    "fmt"
    "math/rand"
    "time"
)

// 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
}

<ins>// 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
}</ins>

// Init sets initial values for variables used in the function.
func init() {
    rand.Seed(time.Now().UnixNano())
}

// 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))]
}
</pre>

    <p>
      In this code, you:
    </p>

    <ul>
      <li>
        Add a <code>Hellos</code> function whose parameter is a slice of names
        rather than a single name. Also, you change one of its return types from
        a <code>string</code> to a <code>map</code> so you can return names
        mapped to greeting messages.
      </li>
      <li>
        Have the new Hellos function call the existing Hello function. This
        leaves both functions in place.
      </li>
      <li>
        Create a <code>messages</code>
        <a href="https://blog.golang.org/maps">map</a> to associate each of the
        received names (as a key) with a generated message (as a value). In Go,
        you initialize a map with the following syntax:
        <code>make(map[<em>key-type</em>]<em>value-type</em>)</code>. You have
        the <code>Hellos</code> function return this map to the caller.
      </li>
      <li>
        Loop through the names your function received, checking that each has a
        non-empty value, then associate a message with each. In this
        <code>for</code> loop, <code>range</code> returns two values: the index
        of the current item in the loop and a copy of the item's value. You
        don't need the index, so you use the Go
        <a href="https://golang.org/doc/effective_go.html#blank"
          >blank identifier (an underscore)</a
        >
        to ignore it.
      </li>
    </ul>
  </li>

  <li>
    In your hello/hello.go calling code, pass a slice of names, then print the
    contents of the names/messages map you get back.

    <p>
      In hello.go, change your code so it looks like the following.
    </p>

    <pre>
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)

    <ins>// A slice of names.
    names := []string{"Gladys", "Samantha", "Darrin"}</ins>

    // 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)
}
</pre>

    <p>
      With these changes, you:
    </p>

    <ul>
      <li>
        Create a <code>names</code> variable as a slice type holding three
        names.
      </li>
      <li>
        Pass the <code>names</code> variable as the argument to the
        <code>Hellos</code> function.
      </li>
    </ul>
  </li>

  <li>
    At the command line, change to the directory that contains hello/hello.go,
    then run hello.go to confirm that the code works.

    <p>
      The output should be a string representation of the map associating names
      with messages, something like the following:
    </p>

    <pre>
$ go run hello.go
map[Darrin:Hail, Darrin! Well met! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]
</pre
    >
  </li>
</ol>

<p>
  This topic introduced maps for representing name/value pairs. It also
  introduced the idea of
  <a href="https://blog.golang.org/module-compatibility"
    >preserving backward compatibility</a
  >
  by implementing a new function for new or changed functionality in a module.
  In the tutorial's <a href="add-a-test.html">next topic</a>, you'll use
  built-in features to create a unit test for your code.
</p>

<p class="Navigation">
  <a class="Navigation-prev" href="random-greeting.html"
    >&lt; Return a random greeting</a
  >
  <a class="Navigation-next" href="add-a-test.html">Add a test &gt;</a>
</p>
