Like Share Discussion Bookmark Smile

J.J. Huang   2020-11-06   Golang   瀏覽次數:

Go - 第九章 | 多人的問候返回

簡要

在你對模塊程式碼進行的最後更改中,你將添加支持在一個請求中為多個人打招呼。換句話說,你將處理多值輸入並將值與多值輸出配對。

為此,你需要將一組名稱傳遞給可以為每個名稱返回問候語的函數。將Hello函數的參數從單個名稱更改為一組名稱將更改函數簽名。如果你已經發布了該greetings模塊,並且用戶已經編寫了程式碼調用Hello,那麼所做的更改將破壞他們的程序。在這種情況下,更好的選擇是給新功能起一個新名字。

在你將在本教程中添加的最後一個程式碼中,更新程式碼,就好像你已經發布了該greetings模塊的版本一樣。無需更改Hello功能,而是添加帶有Hellos一組名稱的新功能 。然後,為簡單起見,讓新函數調用現有函數。將這兩個功能都保留在程序包中,將原來的功能留給現有呼叫者(或僅需要一個問候語的未來呼叫者),並為需要擴展功能的呼叫者添加一個新功能。

開始

  • greetings / greetings.go中,更改程式碼,如下所示。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    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
    }

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

    // 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))]
    }
    • 在此程式碼中,你:
      • 添加一個Hellos函數,該函數的參數是名稱的切片而不是單個名稱。另外,你可以將其返回類型之一從a更改stringmap以便可以返回映射到問候消息的名稱。
      • 讓新的Hellos函數調用現有的Hello函數。這將兩個功能保留在原位。
      • 創建一個messages映射,以將每個接收到的名稱(作為鍵)與生成的消息(作為值)相關聯。在Go中,你可以使用以下語法初始化map:你具有將該map返回給調用方的函數 make(map[key-type]value-type)
      • 循環瀏覽你的函數收到的名稱,檢查每個函數是否具有非空值,然後將消息與每個函數相關聯。在此for循環中,range返回兩個值:循環中當前項目的索引和該項目的值的副本。你不需要索引,因此可以使用Go空白標識符(下劃線) 將其忽略。
  • 在你的hello / hello.go調用程式碼中,傳遞一部分名稱,然後打印你返回的名稱/消息映射的內容。
    • hello.go中,更改程式碼,如下所示。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      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)
      }
    • 通過這些更改,你:
      • 創建一個names包含三個名稱的切片類型變量。
      • names變量作為參數傳遞給Hellos函數。
  • 在命令行上,轉到包含hello / hello.go的目錄,然後運行hello.go確認程式碼可以正常工作。
    • 輸出應該是將名稱與消息相關聯的映射的字符串表示形式,如下所示:
      1
      2
      go run ./hello.go
      map[Darrin:Hi, Darrin. Welcome! Gladys:Great to see you, Gladys! Samantha:Hi, Samantha. Welcome!]

過程

單字/句子

單字/句子 翻譯
signature 簽名
functionality 功能性
sake of simplicity 為了簡單
original 原版的
expanded 擴大了
rather 寧可
This leaves both 這都留下
associate 關聯
received 已收到
identifier 識別碼
holding 保持

結語

本章重點在於,可以使用array傳入多個參數用於對應多個回應,回應的部分使用的是map的方式做回傳;通過為模塊中的新功能或更改功能實現新功能來保持向後兼容性的想法,新建一個Hellos函數,保留了原本的Hello。


註:以上參考了
Golang Documentation