1、代码
2、编译及运行
1、目录结构
1.1)
$ tree
.
├── mplayer.go
└── src
├── mlib
│ ├── manager.go
│ └── manager_test.go
└── mp
├── mp3.go
└── play.go
1.2)mlib库的代码
1.2.1)manager.go代码
package library import "errors" type MusicEntry struct {
Id string
Name string
Artist string
Genre string
Source string
Type string
} type MusicManager struct {
musics []MusicEntry
} func NewMusicManager() * MusicManager {
return &MusicManager {make( []MusicEntry, 0)}
} func (m * MusicManager) Len() int {
return len(m.musics);
} func (m* MusicManager ) Get(index int) (music * MusicEntry, err error) {
if index < 0 || index >= len(m.musics) {
return nil, errors.New("Index out of range.")
} return &m.musics[index], nil
} func (m * MusicManager) Find (name string) * MusicEntry {
if len(m.musics) == 0 {
return nil
} for _,m := range m.musics {
if m.Name == name {
return &m
}
}
return nil
} func (m * MusicManager) Add (music * MusicEntry) {
m.musics = append(m.musics, * music)
} func (m * MusicManager) Remove (index int) * MusicEntry {
if index < 0 || index >= len(m.musics) {
return nil
}
removedMusic := &m.musics[index] if index < len(m.musics) - 1 {
m.musics = append(m.musics[:index - 1], m.musics[index + 1:]...)
}else if index == 0 {
m.musics = make([]MusicEntry, 0)
} else {
m.musics = m.musics[:index - 1]
} return removedMusic
} func (m * MusicManager) RemoveByName (name string) * MusicEntry {
var removedMusic * MusicEntry = nil
var iPos int = -1
for i := 0; i < m.Len(); i++ {
if m.musics[i].Name == name {
iPos = i
break
}
} if iPos < 0 {
return nil
} removedMusic = m.Remove(iPos) return removedMusic
}
1.2.2)manager.go的测试代码manager_test.go
package library import (
"testing"
) func TestOps(t * testing.T) {
mm := NewMusicManager()
if mm == nil {
t.Error("NewMusicManager faild.");
}
if mm.Len() != 0 {
t.Error("NewMusicManager faild, not empty")
}
m0 := &MusicEntry { "1", "My Heart Will Go On", "Celion Dion", "Pop", "http://qbox.me/24501234", "MP3" }
mm.Add(m0) if mm.Len() != 1 {
t.Error("MusicManager.Add faild.")
} m := mm.Find(m0.Name)
if m == nil {
t.Error("MusicManager.Find faild")
} if m.Id != m0.Id ||
m.Name != m0.Name ||
m.Artist != m0.Artist ||
m.Genre != m0.Genre ||
m.Source != m0.Source ||
m.Type != m0.Type {
t.Error("MusicManager.Find() faild. Found item mismatch.")
} m, err := mm.Get(0)
if m == nil {
t.Error("MusicManager.Get() faild.", err)
} m = mm.Remove(0)
if m == nil || mm.Len() != 0 {
t.Error("MusicManager.Remove() faild.", err)
}
}
1.3)mp库代码
1.3.1)src/mp/mp3.go代码
package mp import (
"fmt"
"time"
) type MP3Player struct {
stat int
progress int
} type WAVPlayer struct {
stat int
progress int
} func (p * MP3Player) Play (source string) {
fmt.Println("Playing MP3 music", source) p.progress = 0 for p.progress < 100 {
time.Sleep(100 * time.Millisecond)
fmt.Print(".")
p.progress += 10
}
fmt.Println("\nFinished playing", source)
} func (p * WAVPlayer) Play (source string) {
fmt.Println("Playing WAV music", source) p.progress = 0 for p.progress < 100 {
time.Sleep(100 * time.Millisecond)
fmt.Print(".")
p.progress += 10
}
fmt.Println("\nFinished playing", source)
}
1.3.2)src/mp/play.go代码
package mp import "fmt" type Player interface {
Play(source string)
} func Play(source, mtype string) {
var p Player switch mtype {
case "MP3" :
p = &MP3Player{}
case "WAV" :
p = &WAVPlayer{}
default :
fmt.Println("Unsupported music type", mtype)
return
}
p.Play(source)
}
1.4)main package模块代码mplayer.go
package main import (
"bufio"
"fmt"
"os"
"strconv"
"strings" "mlib"
"mp"
) var lib * library.MusicManager
var id int = 1
var ctrl, signal chan int func handleLibCommands(tokens []string) {
switch tokens[1] {
case "list" :
for i := 0; i < lib.Len(); i++ {
e, _ := lib.Get(i)
fmt.Println(i + 1, ":", e.Name, e.Artist, e.Source, e.Type)
}
case "add" :
if len(tokens) == 7 {
id++
lib.Add(&library.MusicEntry { strconv.Itoa(id), tokens[2], tokens[3], tokens[4], tokens[5], tokens[6] })
} else {
fmt.Println("USAGE : lib add <name><artist><genre><source><type> (7 argv)")
}
case "remove" :
if len(tokens) == 3 {
lib.RemoveByName(tokens[2])
} else {
fmt.Println("USAGE: lib remove <name>")
}
default :
fmt.Println("Unrecogized lib command: ", tokens[1])
}
} func handlePlayCommands(tokens []string) {
if len(tokens) != 2 {
fmt.Println("USAGE : play <name>")
return
} e := lib.Find(tokens[1])
if e == nil {
fmt.Println("The music", tokens[1], "does not exist.")
return
} mp.Play(e.Source, e.Type)
} func main() {
fmt.Println(`
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
`)
lib = library.NewMusicManager() r := bufio.NewReader(os.Stdin) for i := 0; i <= 100; i++ {
fmt.Print("Enter command-> ")
rawLine, _, _ := r.ReadLine() line := string(rawLine)
if line == "q" || line == "e" {
break
}
tokens := strings.Split(line, " ") if tokens[0] == "lib" {
handleLibCommands(tokens)
} else if tokens[0] == "play" {
handlePlayCommands(tokens)
} else {
fmt.Println("Unrecognized command :", tokens[0])
}
}
}
2)编译及运行
2.1)设置环境GOPATH
$ export GOPATH="/home/normal/musicplayer"
2.2)编译
$ go build
2.3)查看编译后的目录结构
.
├── mplayer.go
├── musicplayer
└── src
├── mlib
│ ├── manager.go
│ └── manager_test.go
└── mp
├── mp3.go
└── 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
: 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> ( argv)
Enter command-> lib add a b c d MP3
Enter command-> lib list
: a b d MP3
Enter command-> play a
Playing MP3 music d
..........
Finished playing d
Enter command-> q
注:代码来源《Go语言编程》第三章,代码结构与原书有差别