<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、使用简单,设计也简单;

GO语言(六)接口使用的更多相关文章

  1. R语言数据接口

    R语言数据接口 R语言处理的数据一般从外部导入,因此需要数据接口来读取各种格式化的数据 CSV # 获得data是一个数据帧 data = read.csv("input.csv" ...

  2. [日常] Go语言圣经--接口约定习题

    Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...

  3. FFI (语言交互接口(Foreign Function Interface))

    FFI(Foreign Function Interface)是用来与其它语言交互的接口, 在有些语言里面称为语言绑定(language bindings), Java 里面一般称为 JNI(Java ...

  4. python语言(六)mock接口开发、发邮件、写日志、新Excel操作

    一.urllib模块 urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib模块,在python2里面有urllib模块和urllib2模块. url ...

  5. C语言原子接口与实现

    原子是一个指向唯一的.不可变的0个或任意多个字节序列的指针,大多数原子都是指向以空字符结束的字符串,但是任何一个指向任意字节序列的指针都可以使原子.任何原子只能出现一次.如果两个原子指向同一个内存单元 ...

  6. c语言调试接口

    http://blog.chinaunix.net/uid-10106787-id-2985587.html 在C语言程序设计中,常会出现各种各样的bug:段错误.参数异常等等.我们需要尽快定位错误, ...

  7. Java语言Socket接口用法详解

    Socket接口用法详解   在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...

  8. Go语言的接口

    一.接口的定义和好处 我们都知道接口给类提供了一种多态的机制,什么是多态,多态就是系统根据类型的具体实现完成不同的行为. 以下代码简单说明了接口的作用 package main import ( &q ...

  9. go语言学习-接口

    Go语言中虽然没有传统面向对象语言中类.集成的概念,不过提供了接口的支持,可以使用接口来使用一些面向对象的特性. 在 go 语言中,的接口有下面几个特点: 可以包含0个或多个方法的签名 只定义方法的签 ...

  10. Go语言的接口interface、struct和组合、继承

    Go语言的interface概念相对于C++中的基类,通过interface来实现多态功能. 在C++中,当需要实现多态功能时,步骤是首先定义一个基类,该基类使用虚函数或者纯虚函数抽象了所有子类会用到 ...

随机推荐

  1. 转 Hibernate中cascade和inverse的作用

    Inverse和cascade是Hibernate映射中最难掌握的两个属性.两者都在对象的关联操作中发挥作用.1.明确inverse和cascade的作用inverse 决定是否把对对象中集合的改动反 ...

  2. 【Docker】Docker是什么?怎么安装?怎么用?

     从今天开始学习Docker,通过对网上资料的搜集与学习,记录一下. 是什么 ? Docker是一个基于LXC实现的类似于VMs的超轻量级虚拟机. 它与VMs的区别在于,VMs提供的是一个完整的操作系 ...

  3. Android规划周期任务

    问题:应用总要周期性的执行某项任务,例如检查服务器上的更新或者提醒用户做某些事情. 解决方案:用AlarmManager来管理和执行任务.AlarmManager可用于计划未来的单次或重复操作,甚至在 ...

  4. spring-session-data-redis使用redis共享session

    1:添加jar包 <dependency> <groupId>org.springframework.data</groupId> <artifactId&g ...

  5. Golang教程:并发介绍

    Go是并发语言,而不是并行语言.在讨论Go并发性之前,我们必须首先了解什么是并发,以及并发与并行的区别. 什么是并发 并发(concurrency)是指一次处理大量事情的能力.让我们用一个例子来说明. ...

  6. css多行本文垂直集中

    <div style="display:table;height:400px;"> <span style="display:table-cell;ve ...

  7. SPOJ QTREE6

    题意 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.有两种操作 \(0\ u\):询问有多少个节点\(v\)满足路径\(u\)到\(v\) ...

  8. Python入门-内置函数一

    什么是内置函数?就是python给你提供的拿来直接用的函数,比如print,input等等,截止到python版本3.6.2 python一共提供了68个内置函数,他们就是python直接提供给我们的 ...

  9. Angular的生命周期钩子

    没有什么不能用一张图来解决.

  10. 配合sublime使用flexible.js实现微信开发页面自适应

    什么是flexible.js 是一个终端设备适配的解决方案.也就是说它可以让你在不同的终端设备中实现页面适配. 是一个用来适配移动端的javascript框架.根据宽度的不同设置不同的字体大小,样式间 ...