GO语言(六)接口使用
<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语言(六)接口使用的更多相关文章
- R语言数据接口
R语言数据接口 R语言处理的数据一般从外部导入,因此需要数据接口来读取各种格式化的数据 CSV # 获得data是一个数据帧 data = read.csv("input.csv" ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- FFI (语言交互接口(Foreign Function Interface))
FFI(Foreign Function Interface)是用来与其它语言交互的接口, 在有些语言里面称为语言绑定(language bindings), Java 里面一般称为 JNI(Java ...
- python语言(六)mock接口开发、发邮件、写日志、新Excel操作
一.urllib模块 urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib模块,在python2里面有urllib模块和urllib2模块. url ...
- C语言原子接口与实现
原子是一个指向唯一的.不可变的0个或任意多个字节序列的指针,大多数原子都是指向以空字符结束的字符串,但是任何一个指向任意字节序列的指针都可以使原子.任何原子只能出现一次.如果两个原子指向同一个内存单元 ...
- c语言调试接口
http://blog.chinaunix.net/uid-10106787-id-2985587.html 在C语言程序设计中,常会出现各种各样的bug:段错误.参数异常等等.我们需要尽快定位错误, ...
- Java语言Socket接口用法详解
Socket接口用法详解 在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...
- Go语言的接口
一.接口的定义和好处 我们都知道接口给类提供了一种多态的机制,什么是多态,多态就是系统根据类型的具体实现完成不同的行为. 以下代码简单说明了接口的作用 package main import ( &q ...
- go语言学习-接口
Go语言中虽然没有传统面向对象语言中类.集成的概念,不过提供了接口的支持,可以使用接口来使用一些面向对象的特性. 在 go 语言中,的接口有下面几个特点: 可以包含0个或多个方法的签名 只定义方法的签 ...
- Go语言的接口interface、struct和组合、继承
Go语言的interface概念相对于C++中的基类,通过interface来实现多态功能. 在C++中,当需要实现多态功能时,步骤是首先定义一个基类,该基类使用虚函数或者纯虚函数抽象了所有子类会用到 ...
随机推荐
- An internal error occurred during: "Initializing Java Tooling". Eclipse启动发生的错误
An internal error occurred during: “Initializing Java Tooling” 错误经常是莫名其妙的出现这种总错误,解决办法: 1.eclipse -&g ...
- jquery 部分函数源码解析
JSON.stringify源码(在看extend文档的时候看到) var object1 = { apple: 0, banana: {weight: 52, price: 100}, cherry ...
- 【ExtJS】关于Component生命周期
很久以前就学习过extjs的组件生命周期,很久之后,再回头看一看,又增加好多新的认识. extjs组件生命周期大体分为3个阶段:初始化.渲染.销毁. 第一阶段:初始化 初始化工作开始于组件的诞生,所有 ...
- js模块加载框架 sea.js学习笔记
seajs实现了JavaScript 的 模块开发及按模块加载.用来解决繁琐的js命名冲突,文件依赖等问题,其主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载. 官方文档:http:/ ...
- 9、在Shell脚本中调用其他脚本
在Shell脚本的执行过程中,Shell脚本支持调用另一个Shell脚本,调用的格式为:程序名 实例:在Shell脚本test1中调用test2. 1.调用test2#test1脚本root@ubun ...
- 九度oj 1002 Grading 2011年浙江大学计算机及软件工程研究生机试真题
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #inclu ...
- Django 入门项目案例开发(下)——创建项目应用及模型类
关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. 前面两章是在已经开发好的项目上用来描述环境和业务,这一章创建一个全新的项目来用作开发,你可以跟 ...
- Mybatis Dao开发方法(二)
使用Mapper代理的方式进行开发 Mapper开发的原理 使用Mybatis的Mapper代理方式进行开发,使用该方式,只需要编写Mapper接口,不再需要编写实现类,由Mybatis框架通过接 ...
- Java调用打印机打印指定路径图片
依赖 javax.print package com.xgt.util; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; ...
- MySQL触发器基本使用
文章参考:这里 MySQL中,创建触发器的基本语法: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EA ...