gpt4 book ai didi

go - io.MultiWriter vs. golang 的传值

转载 作者:IT王子 更新时间:2023-10-29 02:04:12 26 4
gpt4 key购买 nike

我想创建一种情况,其中所有内容都设置为特定日志。记录器也附加到特定变量的字符串数组。

变量的类型实现了 io.Writer 接口(interface),因此通过 io.MultiWriter 将其添加到 log.New() 应该很容易,但我似乎遇到了一个棘手的问题:io.Writer 接口(interface)是固定的,并且鉴于 golang 的按值传递,变量不可能引用自身。

也许举个例子会更有意义:

package main

import "fmt"
import "io"
import "log"
import "os"
import "strings"

var Log *log.Logger

type Job_Result struct {
Job_ID int64
// other stuff
Log_Lines []string
}

// satisfies io.Writer interface
func (jr Job_Result) Write (p []byte) (n int, err error) {
s := strings.TrimRight(string(p),"\n ")
jr.Log_Lines= append(jr.Log_Lines,s)
return len(s), nil
}

func (jr Job_Result) Dump() {
fmt.Println("\nHere is a dump of the job result log lines:")
for n, s := range jr.Log_Lines{
fmt.Printf("\tline %d: %s\n",n,s)
}
}

func main() {

// make a Job_Result

var jr Job_Result
jr.Job_ID = 123
jr.Log_Lines = make([]string,0)

// create an io.MultiWriter that points to both stdout
// and that Job_Result var

var writers io.Writer
writers = io.MultiWriter(os.Stdout,jr)

Log = log.New(writers,
"",
log.Ldate|log.Ltime|log.Lshortfile)

// send some stuff to the log

Log.Println("program starting")
Log.Println("something happened")
Log.Printf("last thing that happened, should be %drd line\n",3)

jr.Dump()

}

这是输出,这并不奇怪:

2016/07/28 07:20:07 testjob.go:43: program starting
2016/07/28 07:20:07 testjob.go:44: something happened
2016/07/28 07:20:07 testjob.go:45: last thing that happened, should be 3rd line

Here is a dump of the job result log lines:

我理解这个问题 - Write() 正在获取 Job_Result 变量的副本,因此它尽职尽责地附加,然后副本消失,因为它是本地的。我应该向它传递一个指向 Job_Result 的指针...但我不是调用 Write() 的人,它是由 Logger 完成的,我无法更改它。

我认为这是将日志输出捕获到数组中的简单解决方案(还有其他我没有展示的订阅/取消订阅内容),但这一切都归结为这个有问题的 io.Write() 接口(interface)。

飞行员失误?糟糕的设计?我不是在摸索吗?感谢您的任何建议。

最佳答案

重新定义写函数(现在是指针接收者)

// satisfies io.Writer interface
func (jr *Job_Result) Write (p []byte) (n int, err error) {
s := strings.TrimRight(string(p),"\n ")
jr.Log_Lines= append(jr.Log_Lines,s)
return len(s), nil
}

初始化

jr := new(Job_Result) // makes a pointer.

休息保持原样。这样,*Job_Result 仍然实现了 io.Writer,但不会丢失状态。

go tutorial已经说过,当一个方法修改receiver时,你应该使用指针receiver,否则修改可能会丢失。使用指针而不是实际对象几乎没有什么缺点,当你想确保只有一个对象时。 (是的,从技术上讲,它不是对象)。

关于go - io.MultiWriter vs. golang 的传值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38639365/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com