ランダムな挨拶を返す

このセクションでは、毎回単一の挨拶を返すのではなく、事前に定義された複数の挨拶メッセージのいずれかを返すようにコードを変更します。

これを行うには、Go のスライスを使用します。スライスは配列に似ていますが、アイテムの追加と削除に応じてサイズが動的に変化するという点が異なります。スライスは Go の最も有用な型の一つです。

3つの挨拶メッセージを含む小さなスライスを追加し、コードがそのメッセージのいずれかをランダムに返すようにします。スライスの詳細については、Go ブログのGo スライスを参照してください。

  1. greetings/greetings.go で、コードを次のように変更します。
    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
    }
    
    // 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 a randomly selected message format by specifying
        // a random index for the slice of formats.
        return formats[rand.Intn(len(formats))]
    }
    

    このコードでは、以下のことを行います。

    • 挨拶メッセージのランダムに選択された形式を返すrandomFormat関数を追加します。randomFormatが小文字で始まることに注意してください。これにより、独自のパッケージ内のコードからのみアクセス可能になります(つまり、エクスポートされません)。
    • randomFormatで、3つのメッセージ形式を持つformatsスライスを宣言します。スライスを宣言する際は、次のようにブラケット内のサイズを省略します: []string。これは、スライスの基になる配列のサイズを動的に変更できることを Go に伝えます。
    • スライスからアイテムを選択するための乱数を生成するために、math/randパッケージを使用します。
    • Helloで、randomFormat関数を呼び出して返すメッセージの形式を取得し、その形式とname値を組み合わせてメッセージを作成します。
    • 以前と同じようにメッセージ(またはエラー)を返します。
  2. hello/hello.go で、コードを次のように変更します。

    hello.go のHello関数呼び出しの引数として、Gladysの名前(または好きな別の名前)を追加するだけです。

    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)
    
        // Request a greeting message.
        message, err := greetings.Hello("Gladys")
        // If an error was returned, print it to the console and
        // exit the program.
        if err != nil {
            log.Fatal(err)
        }
    
        // If no error was returned, print the returned message
        // to the console.
        fmt.Println(message)
    }
  3. コマンドラインで、helloディレクトリでhello.goを実行して、コードが機能することを確認します。複数回実行し、挨拶が変化することに注目してください。
    $ go run .
    Great to see you, Gladys!
    
    $ go run .
    Hi, Gladys. Welcome!
    
    $ go run .
    Hail, Gladys! Well met!
    

次に、スライスを使用して複数の人々に挨拶します。