はじめに
今回は、 いままで作成した greetings モジュール を変更し、 毎回同じ文字列を返却する仕組み だったものから、 事前に登録されていたいくつかの挨拶文字列からランダムで 1 つ選び返却する仕組み にします。
当エントリは以下のエントリの続きとなっています。事前に一読しておくことをおすすめします。
今回の仕組みを実現するために、 Go 言語に用意されている **スライス ( slice ) ** という組み込み型を利用します。
スライス ( slice ) とは?
配列 ( array ) に似ている組み込み型です。
「配列」 は格納できる要素数が固定です。
「スライス」 は要素を追加したり削除された場合に動的にサイズが変更される「配列」です。
Go 言語における便利な組み込み型の一つです。
他のエントリでスライスについて詳しく取り上げてみましたので、是非参考ください!
コーディング開始
ここでは、挨拶文言を 3 つ用意し、スライスに格納しておくことにしましょう。
このスライスからランダムに要素を選び、関数の戻り値に利用します。
1. 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
| package greetings
import (
"errors"
"fmt"
"math/rand"
"time"
)
func Hello(name string) (string, error) {
if name == "" {
return "", errors.New("empty name")
}
message := fmt.Sprintf(randomFormat(), name)
return message, nil
}
func init() {
rand.Seed(time.Now().UnixNano())
}
func randomFormat() string {
formats := []string{
"Hi, %v. Welcome!",
"Great to see you, %v!",
"Hail, %v! Well met!",
}
return formats[rand.Intn(len(formats))]
}
|
前回からの差分は以下になります。
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
| $ git diff
diff --git greetings.go greetings.go
index 1e584b1..9cde4e7 100644
--- greetings.go
+++ greetings.go
@@ -3,6 +3,8 @@ package greetings
import (
"errors"
"fmt"
+ "math/rand"
+ "time"
)
func Hello(name string) (string, error) {
@@ -10,7 +12,21 @@ func Hello(name string) (string, error) {
return "", errors.New("empty name")
}
- message := fmt.Sprintf("Hi, %v. Welcome!", name)
+ message := fmt.Sprintf(randomFormat(), name)
return message, nil
}
+
+func init() {
+ rand.Seed(time.Now().UnixNano())
+}
+
+func randomFormat() string {
+ formats := []string{
+ "Hi, %v. Welcome!",
+ "Great to see you, %v!",
+ "Hail, %v! Well met!",
+ }
+
+ return formats[rand.Intn(len(formats))]
+}
|
コード解説
かんたんに解説します。
randomFormat 関数を追加。- 挨拶文言をランダムで 1 つ返却。
- 関数名の先頭が小文字で始まっていることに注目!パッケージ外からは呼び出せない関数として定義しています。
randomFormat 関数の中では、 foramts というスライスを宣言し 3 つの文字列を格納しています。- スライスは配列と異なり、サイズ指定を省略できます。
math/rand パッケージを使っています。スライスから取り出す要素番号(0〜2)をランダムに決めるために使用しています。init 関数を追加し、 rand 関数のシード(種)を設定しています。- Go では、プログラム開始時に
init 関数が自動的に実行されます。 - その後、グローバル変数の初期化が行われます。
Hello 関数の中では、 randomFormat 関数が呼び出されます。実行結果の文字列から %v の値をパラメータで変換し、返却します。
2. hello/hello.go を開き、 コードを変更
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| package main
import (
"fmt"
"log"
"genzouw/greetings"
)
func main() {
log.SetPrefix("greetings: ")
log.SetFlags(0)
message, err := greetings.Hello("genzouw")
if err != nil {
log.Fatal(err)
}
fmt.Println(message)
}
|
アプリケーション実行
hello モジュールの配置されているディレクトリで、コードを実行してみます。
何度か実行してみると、挨拶文言が異なっているはずです。 ( 同じ文言が連続して出力されることもあります。 )
1
2
3
4
5
6
7
8
| $ go run .
Hi, genzouw. Welcome!
$ go run .
Great to see you, genzouw!
$ go run .
Hail, genzouw! Well met!
|
ひとこと
次回は **Key-Value の仕組みを使って、複数の人々に挨拶文を返却 ** してみます。