GO语言练习:第二个工程

时间:2021-04-07 05:10:05

1、代码

2、编译及运行


 

1、目录结构

  1.1)

 1 $ tree
2 .
3 ├── mplayer.go
4 └── src
5 ├── mlib
6 │   ├── manager.go
7 │   └── manager_test.go
8 └── mp
9 ├── mp3.go
10 └── play.go

  1.2)mlib库的代码

    1.2.1)manager.go代码

 1 package library
2
3 import "errors"
4
5 type MusicEntry struct {
6 Id string
7 Name string
8 Artist string
9 Genre string
10 Source string
11 Type string
12 }
13
14 type MusicManager struct {
15 musics []MusicEntry
16 }
17
18 func NewMusicManager() * MusicManager {
19 return &MusicManager {make( []MusicEntry, 0)}
20 }
21
22 func (m * MusicManager) Len() int {
23 return len(m.musics);
24 }
25
26 func (m* MusicManager ) Get(index int) (music * MusicEntry, err error) {
27 if index < 0 || index >= len(m.musics) {
28 return nil, errors.New("Index out of range.")
29 }
30
31 return &m.musics[index], nil
32 }
33
34 func (m * MusicManager) Find (name string) * MusicEntry {
35 if len(m.musics) == 0 {
36 return nil
37 }
38
39 for _,m := range m.musics {
40 if m.Name == name {
41 return &m
42 }
43 }
44 return nil
45 }
46
47 func (m * MusicManager) Add (music * MusicEntry) {
48 m.musics = append(m.musics, * music)
49 }
50
51 func (m * MusicManager) Remove (index int) * MusicEntry {
52 if index < 0 || index >= len(m.musics) {
53 return nil
54 }
55 removedMusic := &m.musics[index]
56
57 if index < len(m.musics) - 1 {
58 m.musics = append(m.musics[:index - 1], m.musics[index + 1:]...)
59 }else if index == 0 {
60 m.musics = make([]MusicEntry, 0)
61 } else {
62 m.musics = m.musics[:index - 1]
63 }
64
65 return removedMusic
66 }
67
68 func (m * MusicManager) RemoveByName (name string) * MusicEntry {
69 var removedMusic * MusicEntry = nil
70 var iPos int = -1
71 for i := 0; i < m.Len(); i++ {
72 if m.musics[i].Name == name {
73 iPos = i
74 break
75 }
76 }
77
78 if iPos < 0 {
79 return nil
80 }
81
82 removedMusic = m.Remove(iPos)
83
84 return removedMusic
85 }

  1.2.2)manager.go的测试代码manager_test.go

 1 package library
2
3 import (
4 "testing"
5 )
6
7 func TestOps(t * testing.T) {
8 mm := NewMusicManager()
9 if mm == nil {
10 t.Error("NewMusicManager faild.");
11 }
12 if mm.Len() != 0 {
13 t.Error("NewMusicManager faild, not empty")
14 }
15 m0 := &MusicEntry { "1", "My Heart Will Go On", "Celion Dion", "Pop", "http://qbox.me/24501234", "MP3" }
16 mm.Add(m0)
17
18 if mm.Len() != 1 {
19 t.Error("MusicManager.Add faild.")
20 }
21
22 m := mm.Find(m0.Name)
23 if m == nil {
24 t.Error("MusicManager.Find faild")
25 }
26
27 if m.Id != m0.Id ||
28 m.Name != m0.Name ||
29 m.Artist != m0.Artist ||
30 m.Genre != m0.Genre ||
31 m.Source != m0.Source ||
32 m.Type != m0.Type {
33 t.Error("MusicManager.Find() faild. Found item mismatch.")
34 }
35
36 m, err := mm.Get(0)
37 if m == nil {
38 t.Error("MusicManager.Get() faild.", err)
39 }
40
41 m = mm.Remove(0)
42 if m == nil || mm.Len() != 0 {
43 t.Error("MusicManager.Remove() faild.", err)
44 }
45 }

  1.3)mp库代码

    1.3.1)src/mp/mp3.go代码

 1 package mp
2
3 import (
4 "fmt"
5 "time"
6 )
7
8 type MP3Player struct {
9 stat int
10 progress int
11 }
12
13 type WAVPlayer struct {
14 stat int
15 progress int
16 }
17
18 func (p * MP3Player) Play (source string) {
19 fmt.Println("Playing MP3 music", source)
20
21 p.progress = 0
22
23 for p.progress < 100 {
24 time.Sleep(100 * time.Millisecond)
25 fmt.Print(".")
26 p.progress += 10
27 }
28 fmt.Println("\nFinished playing", source)
29 }
30
31 func (p * WAVPlayer) Play (source string) {
32 fmt.Println("Playing WAV music", source)
33
34 p.progress = 0
35
36 for p.progress < 100 {
37 time.Sleep(100 * time.Millisecond)
38 fmt.Print(".")
39 p.progress += 10
40 }
41 fmt.Println("\nFinished playing", source)
42 }

    1.3.2)src/mp/play.go代码

 1 package mp
2
3 import "fmt"
4
5 type Player interface {
6 Play(source string)
7 }
8
9 func Play(source, mtype string) {
10 var p Player
11
12 switch mtype {
13 case "MP3" :
14 p = &MP3Player{}
15 case "WAV" :
16 p = &WAVPlayer{}
17 default :
18 fmt.Println("Unsupported music type", mtype)
19 return
20 }
21 p.Play(source)
22 }

  1.4)main package模块代码mplayer.go

 1 package main
2
3 import (
4 "bufio"
5 "fmt"
6 "os"
7 "strconv"
8 "strings"
9
10 "mlib"
11 "mp"
12 )
13
14 var lib * library.MusicManager
15 var id int = 1
16 var ctrl, signal chan int
17
18 func handleLibCommands(tokens []string) {
19 switch tokens[1] {
20 case "list" :
21 for i := 0; i < lib.Len(); i++ {
22 e, _ := lib.Get(i)
23 fmt.Println(i + 1, ":", e.Name, e.Artist, e.Source, e.Type)
24 }
25 case "add" :
26 if len(tokens) == 7 {
27 id++
28 lib.Add(&library.MusicEntry { strconv.Itoa(id), tokens[2], tokens[3], tokens[4], tokens[5], tokens[6] })
29 } else {
30 fmt.Println("USAGE : lib add <name><artist><genre><source><type> (7 argv)")
31 }
32 case "remove" :
33 if len(tokens) == 3 {
34 lib.RemoveByName(tokens[2])
35 } else {
36 fmt.Println("USAGE: lib remove <name>")
37 }
38 default :
39 fmt.Println("Unrecogized lib command: ", tokens[1])
40 }
41 }
42
43 func handlePlayCommands(tokens []string) {
44 if len(tokens) != 2 {
45 fmt.Println("USAGE : play <name>")
46 return
47 }
48
49 e := lib.Find(tokens[1])
50 if e == nil {
51 fmt.Println("The music", tokens[1], "does not exist.")
52 return
53 }
54
55 mp.Play(e.Source, e.Type)
56 }
57
58 func main() {
59 fmt.Println(`
60 Enter following commands to control the player:
61 lib list --View the existing music lib
62 lib add <name><artist><genre><source><type> -- Add a music to the music lib
63 lib remove <name> --Remove the specified music from the lib
64 play <name> -- Play the specified music
65 `)
66 lib = library.NewMusicManager()
67
68 r := bufio.NewReader(os.Stdin)
69
70 for i := 0; i <= 100; i++ {
71 fmt.Print("Enter command-> ")
72 rawLine, _, _ := r.ReadLine()
73
74 line := string(rawLine)
75 if line == "q" || line == "e" {
76 break
77 }
78 tokens := strings.Split(line, " ")
79
80 if tokens[0] == "lib" {
81 handleLibCommands(tokens)
82 } else if tokens[0] == "play" {
83 handlePlayCommands(tokens)
84 } else {
85 fmt.Println("Unrecognized command :", tokens[0])
86 }
87 }
88 }

  2)编译及运行

    2.1)设置环境GOPATH

$ export GOPATH="/home/normal/musicplayer"

    2.2)编译

1 $ go build

    2.3)查看编译后的目录结构

 1 .
2 ├── mplayer.go
3 ├── musicplayer
4 └── src
5 ├── mlib
6 │   ├── manager.go
7 │   └── manager_test.go
8 └── mp
9 ├── mp3.go
10 └── play.go

    2.4)运行

$ ./musicplayer 

Enter following commands to control the player:
lib list
--View the existing music lib
lib add
<name><artist><genre><source><type> -- Add a music to the music lib
lib remove
<name> --Remove the specified music from the lib
play
<name> -- Play the specified music

Enter command
-> lib add a b c d e
Enter command
-> lib list
1 : a b d e
Enter command
-> play a
Unsupported music type e
Enter command
-> lib remove a
Enter command
-> lib add a b c d e MP3
USAGE : lib add
<name><artist><genre><source><type> (7 argv)
Enter command
-> lib add a b c d MP3
Enter command
-> lib list
1 : a b d MP3
Enter command
-> play a
Playing MP3 music d
..........
Finished playing d
Enter command
-> q

 

注:代码来源《Go语言编程》第三章,代码结构与原书有差别