GO语言(六)接口使用

时间:2021-10-28 23:04:50

<music>

  |------<src>

       |-------<library>

            |-------manager.go

            |-------manager_test.go

       |-------<play>

            |-------play.go

            |-------mp3.go

            |-------wav.go

       |--------<music>

            |-------mplayer.go

  |------<pkg>

  |------<bin>

------------------------------------------------------------------------------------

library:音乐库文件所在目录

[manager.go]

 package  library

 import "errors"

 type MusicEntry struct {
Id string
Name string
Artist string
Source string
Type string
} type MusicManager struct {
musics []MusicEntry
} func NewMusicManager() *MusicManager {
return &MusicManager{make([]MusicEntry, )}
} func (m *MusicManager) Len() int {
return len(m.musics)
} func (m *MusicManager) Get(index int) (music *MusicEntry, err error) {
if index < || 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)== {
return nil
} for _,mm := range m.musics {
if mm.Name == name {
return &mm
}
}
return nil
} func (m *MusicManager)Add(music *MusicEntry) {
m.musics = append(m.musics, *music)
} func (m *MusicManager)Remove(index int) *MusicEntry {
if index< || index >= len(m.musics) {
return nil
} removedMusic := &m.musics[index] if index < len(m.musics)- {
m.musics = append(m.musics[:index-], m.musics[index+:]...)
} else if index == {
m.musics = make([]MusicEntry, )
}else {
m.musics = m.musics[:index-]
}
return removedMusic
}

[manager_test.go]

 package library

 import (
"testing"
) func TestOps(t *testing.T) {
mm := NewMusicManager()
if mm == nil {
t.Error("NewMusicManager() failed.")
}
m0 := &MusicEntry {"", "Cellion Dion", "My Heart Will Go On", "http://qbox.me/24501234", "MP3" }
mm.Add(m0) if mm.Len() != {
t.Error("MusicManager.Add() failed.")
} m := mm.Find(m0.Name) if m == nil {
t.Error("MusicManager.Find() failed.")
} if m.Id != m0.Id || m.Artist != m0.Artist || m.Name != m0.Name || m.Source != m0.Source || m.Type != m0.Type {
t.Error("MusicManager.Find() failed. Found item mismatch.")
} m, err := mm.Get() if m == nil {
t.Error("MusicManager.Get() failed.", err)
} m = mm.Remove()
if m == nil || mm.Len() != {
t.Error("MusicManager.Remove() failed.", err)
}
}

play:各种音乐类型存放库

[play.go]

 package play

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

[mp3.go]

 package play

 import (
"fmt"
"time"
) type MP3Player struct {
stat int
progress int
} func (p *MP3Player)Play(source string) {
fmt.Println("Playing MP3 music", source) p.progress = for p.progress < {
time.Sleep(*time.Millisecond)
fmt.Print(".")
p.progress +=
} fmt.Println("\nFinished playing", source)
}

[wav.go]

 package play

 import (
"fmt"
"time"
) type WAVPlayer struct {
stat int
progress int
} func (p *WAVPlayer) Play(source string) {
fmt.Println("Playing WAV music", source) p.progress = for p.progress < {
time.Sleep(*time.Millisecond)
fmt.Print(".")
p.progress +=
} fmt.Println("\nFinished playing", source)
}

music:主程序的放在处

[mplayer.go]

 package main

 import  (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"play"
"library"
) var lib *library.MusicManager
var id int =
var ctrl, signal chan int func handleLibCommands(tokens []string) {
switch tokens[] {
case "list" :
for i:=; i<lib.Len(); i++ {
e,_ := lib.Get(i)
fmt.Println(i+, ":", e.Name, e.Artist, e.Source, e.Type)
}
case "add":
if len(tokens) == {
id++
lib.Add(&library.MusicEntry{string(strconv.Itoa(id)),tokens[],tokens[],tokens[],tokens[]})
}else {
fmt.Println("USAGE: library add <name><artist><source><type>")
}
case "remove":
if len(tokens) == {
lib.Remove() // 有问题
} else {
fmt.Println("USAGE: library remove <name>")
}
default:
fmt.Println("Unrecongnized library command:", tokens[])
}
} func handlePlayCommands(tokens []string) {
if len(tokens) != {
fmt.Println("USAGE: play <name>")
return
} e := lib.Find(tokens[]) if e == nil {
fmt.Println("The music", tokens[], "does not exist.")
return
} play.Play(e.Source, e.Type)
} func main() {
fmt.Println(`
Enter following commands to control the player:
lib add <name><artist><source><type>
lib remove <name>
play <name>
`) lib = library.NewMusicManager() r := bufio.NewReader(os.Stdin) for {
fmt.Println("Enter command->") rawLine,_,_ := r.ReadLine() line := string(rawLine) if line == "q" || line == "e" {
break
} tokens := strings.Split(line, " ") if tokens[] == "lib" {
handleLibCommands(tokens)
}else if tokens[] == "play" {
handlePlayCommands(tokens)
}else {
fmt.Println("Unrecongnized command:", tokens[])
}
}
}

;之后,返回到music目录节点,执行如下命令:

go build library

go build play

go build music

go test library

go install library

go install play

go install music

--------------------------------------------------------------------

接口使用的感受:

  1、类似于C++中虚基类的作用,作为一个消费者的接口,用于接收生产者设计的方法;

  2、生产者设计也简单,只需要实现接口中的方法就算设计了接口【无需如C++的,还需要继承】;

  3、使用简单,设计也简单;