我有创建一个"脚本"将走一个目录树来对文件进行分类并采取行动(如果是照片,则上传到Flickr。如果是视频,请移动到文件夹,......)。
我没有Go的知识,但想改变它。文件发现和分类似乎不是最重要的部分。 例程和频道似乎足以拥有非阻塞系统。
我主要关心的是采取的行动。我一定会编写一些动作,例如" FlickrUpload"或者" Shell" (适用于mv
,cp
,..)。但我希望有一个可配置的系统,我可以将动作附加到mime类型。我认为一个Xml结构可以很好地配置它,并且看起来很容易解析。
<?xml version="1.0" standalone="yes">
<configuration>
<file type="image/jpg">
<action name="FlickrUpload" />
<action name="Shell">
mv ${file} /some/absolute/path/
</action>
<!-- or -->
<FlickrUpload />
</file>
</configuration>
但我不知道如何将动作及其参数(从Xml)绑定到action
interface
(除非你说其他)。
type action interface {
execute(path string) error
}
答案 0 :(得分:3)
从XML流或任何其他文本媒体中,您只能获取文本。
因此,您的mv ${file} /some/absolute/path/
基本上是文字。
这意味着在实际调用之前,您将不可避免地需要解析它 你解决的任何问题都是真实的行动。
现在你有两个问题:
它们交织在一起 - 取决于你如何决定解决(1)。
第一种调用Go函数的方法是给出文本“句柄” 只需要有一个这样的函数句柄的映射,如下所示:
type Action func (...interface{}) error
var actions = map[string]Action {
"mv": Move,
"flickr": UploadToFlickr,
}
func Move(args ...interface{}) error {
// implement
}
func UploadToFlickr(args ...interface{}) error {
// implement
}
现在你发送你的行为,如
act, ok := actions[action_name]
if !ok {
log.Fatalf("Config error: Unsupported action: %s\n', action_name)
}
err := act(action_args...)
if err != nil {
// Handle
}
注意这些
...
位:它们实现了可变参数函数 和允许将一片值传递给一个可变函数。
第二种方法是更严格地输入:
您定义了一个界面:
type Action interface {
func Do(fname string) error
}
您的配置解析代码将生成具体类型的值
比方说,MoveAction
,FlickrUploadAction
。
所有这些类型都必须实现接口Do()
的方法Action
。
通过这样做,他们自动地实现了所述界面。 这也意味着您的配置解析器可以返回该值 接口 - 像这样:
func ConfigParser() (map[string]Action, error)
...其中map[string]Action
将映射MIME类型的文件
具体类型的值 - 例如FlickrUploadAction
对于类型为文件的image/png
和MoveAction
类型的文件
text/plain
。
要调用操作,您可以查找由该虚构生成的地图
ConfigParser()
函数使用文件的MIME类型并获取值
它实现了Action
接口,所以剩下的就是简单
调用其Do()
方法传递实际文件的名称。
阅读界面 - 它们非常强大且无处不在
在标准库中(查看io.Reader
和io.Writer
s)。