请问在go里如何实现多态?

我现在在用go做个小工具,本地文件浏览器,就是执行程序后,打开浏览器并展示定义的目录下的所有文件名列表,点击某个文件名,会根据文件后缀名打开不同的模板页面,然后展示对应文件内容。

大致代码示例如下:

我定义了3个 struct

type File struct {//所有 file 的父类
    Name         string `json:"name"`          //文件名,如:001.jpg
    Ext          string `json:"ext"`           //文件后缀名,如:jpg,目录的后缀名为:dir
    RelativePath string `json:"relative_path"` //文件相对于 config.ROOT_DIR 的路径,一定带 /,如:html/
    LastModified int64  `json:"last_modified"` //文件最后修改时间
}

type TextFile struct {//文本类 file
    File    File
    Content string `json:"content"`
}

type ImgFile struct {//图片类 file
    File   File
    Width  int64
    Height int64
}

现在有一个方法:

func GetFileByUrlPath(name string) File {......}

然后对这个返回 的 File 进行 switch 匹配处理:

func (file *File) Open(w http.ResponseWriter) {
    switch file.Ext {
    case "dir":
        showDir(w, file)
    case "jpg", "jpeg", "png", "gif":
        showImgFile(w, file)
    case "mp4", "avi":
        showVideoFile(w, file)
    case "mp3":
    case "pdf":
    case "css", "html", "htm", "go", "txt", "log":
        showTextFile(w, file)
    default:
        showDefault(w, file)
    }
}

我觉得这个 Open 方法写的十分 low,一直在思考是否能通过多态实现?奈何资质愚笨,想不通,特请大神指点一二,在下感激涕零!

阅读 1.8k
2 个回答

go不存在继承,但是可以利用go的鸭子类型的特性实现多态你可以看看这篇文章,https://www.jianshu.com/p/b333c5f34ef6

image.png

type File interface {
    Show(w *ResponseWriter)
}

type Factory map[string]func(path string) File

func (f *Factory) register(pattern string, func(path string) File) error {
    // pattern 重复检查
}

func (f *Factory) Open(path string) (File, error) {
    // 1. 尝试用保存的 pattern 匹配 path,比如 *.jpg 匹配 /path/to/1.jpg
    // 2. 匹配成功则调用保存的函数,传入 path,得到 File,返回
    // 3. 若没有匹配则使用默认方法(或者报错退出)
}

type JPEGFile struct {
    // ...
}

func (*JPEGFile) Show(w *ResponseWriter) {
    // ...
}

// ... 定义你的类型,实现 File 接口

func NewJPEGFile(path string) File {
    // ... 构造 JPEGFile 结构
}

func init() {
    factory.register("*.jpg", NewJPEGFile)
    // ... 以此类推,注册文件类型
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题