考虑一下这个工作样例代码,它扩展了(不完全)
type multiWriter struct {
writers []Writer
}在io包中,只添加两个名为Remove和Append的方法来操作内部切片writers
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)
}有没有简洁的方法可以做到这一点,只将两个方法Remove和Append添加到io.MultiWriter中
发布于 2016-07-18 11:24:22
不能为其他包中的类型定义方法。代码只能为同一包中的类型定义方法。
由
T表示的类型称为接收基类型;它不能是指针或接口类型,必须在与方法相同的包中声明。
因此,除了复制其完整代码并将方法添加到您自己的类型之外,没有其他方法可以扩展未导出的io.multiWriter类型。
备注:作为实现说明,在您的multiWriter.Remove()方法中,一旦您找到了可移动的编写器,在重新定位之后,您可以“中断”(从内部循环)删除该片的其余部分:
// ...
if t.writers[i] == v {
t.writers = append(t.writers[:i], t.writers[i+1:]...)
break
}
// ...https://stackoverflow.com/questions/38435091
复制相似问题