首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何扩展标准Golang未出口结构类型?

如何扩展标准Golang未出口结构类型?
EN

Stack Overflow用户
提问于 2016-07-18 11:04:20
回答 1查看 1.2K关注 0票数 2

考虑一下这个工作样例代码,它扩展了(不完全)

代码语言:javascript
复制
type multiWriter struct {
    writers []Writer
}

io包中,只添加两个名为RemoveAppend的方法来操作内部切片writers

代码语言:javascript
复制
package main

import (
    "io"
    "os"
)

func main() {
    w1, e := os.Create("file1.txt")
    if e != nil {
        panic(e)
    }
    w2, e := os.Create("file2.txt")
    if e != nil {
        panic(e)
    }
    mw := MultiWriter(w1, w2)
    data := []byte("Hello ")
    _, e = mw.Write(data)
    if e != nil {
        panic(e)
    }

    var m *multiWriter = mw.(*multiWriter)
    m.Remove(w2)
    w2.Close()
    w3, e := os.Create("file3.txt")
    if e != nil {
        panic(e)
    }
    m.Append(w3)
    data = []byte("World ")
    _, e = mw.Write(data)
    if e != nil {
        panic(e)
    }
    w3.Close()
    w1.Close()
}
func (t *multiWriter) Remove(writers ...io.Writer) {
    for i := len(t.writers) - 1; i > 0; i-- {
        for _, v := range writers {
            if t.writers[i] == v {
                t.writers = append(t.writers[:i], t.writers[i+1:]...)
                break
            }
        }
    }
}
func (t *multiWriter) Append(writers ...io.Writer) {
    t.writers = append(t.writers, writers...)
}

type multiWriter struct {
    writers []io.Writer
}

func (t *multiWriter) Write(p []byte) (n int, err error) {
    for _, w := range t.writers {
        n, err = w.Write(p)
        if err != nil {
            return
        }
        if n != len(p) {
            err = io.ErrShortWrite
            return
        }
    }
    return len(p), nil
}

var _ stringWriter = (*multiWriter)(nil)

func (t *multiWriter) WriteString(s string) (n int, err error) {
    var p []byte // lazily initialized if/when needed
    for _, w := range t.writers {
        if sw, ok := w.(stringWriter); ok {
            n, err = sw.WriteString(s)
        } else {
            if p == nil {
                p = []byte(s)
            }
            n, err = w.Write(p)
        }
        if err != nil {
            return
        }
        if n != len(s) {
            err = io.ErrShortWrite
            return
        }
    }
    return len(s), nil
}

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
func MultiWriter(writers ...io.Writer) io.Writer {
    w := make([]io.Writer, len(writers))
    copy(w, writers)
    return &multiWriter{w}
}

// stringWriter is the interface that wraps the WriteString method.
type stringWriter interface {
    WriteString(s string) (n int, err error)
}

有没有简洁的方法可以做到这一点,只将两个方法RemoveAppend添加到io.MultiWriter

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-18 11:24:22

不能为其他包中的类型定义方法。代码只能为同一包中的类型定义方法。

Spec:方法声明:

T表示的类型称为接收基类型;它不能是指针或接口类型,必须在与方法相同的包中声明。

因此,除了复制其完整代码并将方法添加到您自己的类型之外,没有其他方法可以扩展未导出的io.multiWriter类型。

备注:作为实现说明,在您的multiWriter.Remove()方法中,一旦您找到了可移动的编写器,在重新定位之后,您可以“中断”(从内部循环)删除该片的其余部分:

代码语言:javascript
复制
// ...
if t.writers[i] == v {
    t.writers = append(t.writers[:i], t.writers[i+1:]...)
    break
}
// ...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38435091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档