<!--{
    "Title": "Return greetings for 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, then pair values in that input with a
  multiple-value output. To do this, you'll need to pass a set of names to a
  function that can return a greeting for each of them. 
</p>

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

<p>
  But there's a hitch. Changing the <code>Hello</code> function's
  parameter from a single name to a set of names would change the function's
  signature. If you had already published the <code>example.com/greetings</code>
  module and users had already written code calling <code>Hello</code>, that
  change would break their programs.</p>

<p>
  In this situation, a better choice is to write a new function with a different
  name. The new function will take multiple parameters. That preserves the old
  function for backward compatibility.
</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 <code>Hellos</code> function call the existing
        <code>Hello</code> function. This helps reduce duplication while also
        leaving both functions in place.
      </li>
      <li>
        Create a <code>messages</code> map 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. For more
        about maps, see <a href="https://blog.golang.org/maps">Go maps in
        action</a> on the Go blog.
      </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 blank identifier (an underscore)
        to ignore it. For more, see
        <a href="/doc/effective_go.html#blank">The blank
        identifier</a> in Effective Go.
      </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 use <code>go run</code> 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 .
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 preserving backward compatibility
  by implementing a new function for new or changed functionality in a module.
  For more about backward compatibility, see
  <a href="https://blog.golang.org/module-compatibility">Keeping your modules
  compatible</a>.
</p>

<p>Next, you'll use built-in Go features to create a unit test for your code.</p>

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