试图将文字转换为Golang中的指针

To ease testing of the code I'm responsible for testing, I'm refactoring my team's LogHandler.

They had something like this:

type LogHandlerSt struct {
    path        string
    fileName    string
    projectName string
}

var (
    //Instance The project instance of log handler.
    Instance LogHandlerSt
    //OnResponseError A function that can be set to be called on response error.
    OnResponseError func(context interface{}, response *http.Response)
    //includeStack Will include all lines with the strings below in the debug stack.
    includeStack = []string{"apiserver_sdk", "ezdineserver_sdk"}
)

//CreateLogHandler Creates and assigns a log handler instance for use by the project.
func CreateLogHandler(path string, fileName string, projectName string) LogHandlerSt {
    Instance = LogHandlerSt{path: path, fileName: fileName, projectName: projectName}.
        fmt.Println("Log files are in \"" + path + "\"")
    return Instance
}

//log Logs a message given the type of message and the message itself.
func (handler *LogHandlerSt) log(logType string, errMsg string) {
    fmt.Println(errMsg)
    logFile, err := os.OpenFile(handler.path+"/"+handler.fileName+" "+time.Now().Format("2006-01-02")+".log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0777)
    if err != nil {
        fmt.Println(err)
    }
    defer logFile.Close()
    if _, err = logFile.WriteString(`
` + logType + " " + time.Now().Format("2006-01-02 15:04:05.000") + `: ` + errMsg + "
"); err != nil {
        fmt.Println(err)
    }
    logFile.Sync()
}

//GetProjectNames Gets the projects to use for the log handler instance. Usually used for the debug stack.
func (handler *LogHandlerSt) GetProjectNames() []string {
    var projectNames = []string{handler.projectName}
    projectNames = append(projectNames, includeStack...)
    return projectNames
}

//LogError Logs an error given information.
func (handler *LogHandlerSt) LogError(errMsg string) {
    handler.log("Error", errMsg)
}

//LogWarning Logs a warning given information.
func (handler *LogHandlerSt) LogWarning(errMsg string) {
    handler.log("Warn", errMsg)
}

//LogInfo Logs some information.
func (handler *LogHandlerSt) LogInfo(errMsg string) {
    handler.log("Info", errMsg)
}

Many methods in the code base under test use these functions, on Instance. To remedy this, I introduced a struct Logger thusly:

// Logger provides a generic implementation of the required methods.
//  Provided for testing purposes
type Logger interface {
    LogError(errMessage string)
    LogWarning(errMessage string)
    LogInfo(errMessage string)
}

Instincts, especially from Java, told me to change declaration of that Instance to a Logger. This, of course, did nothing, as Logger was an instance whereas the methods were on a *Logger. So, I changed to Instance *Logger and refactored CreateLogHandler to take care of the compile-time error I just created:

//CreateLogHandler Creates and assigns a log handler instance for use by the project.
func CreateLogHandler(path string, fileName string, projectName string) LogHandlerSt {
    Instance = &LogHandlerSt{path: path, fileName: fileName, projectName: projectName}
        fmt.Println("Log files are in \"" + path + "\"")
    return Instance
}

I get told:

cannot use LogHandlerSt literal (type *LogHandlerSt) as type *Logger in assignment:
*Logger is pointer to interface, not interface

WHY NOT, and what can I do about this?

" as Logger was an instance whereas the methods were on a *Logger".

Stop right there. Logger is an interface. Methods are "not on an interface". Concrete implementations have a concrete receiver type, which will be *LogHandlerSt, not *Logger, nor Logger. Also LogHandlerSt does not implement Logger, only *LogHandlerSt as methods are defined with pointer receiver.

If you introduce Logger, this is how you may use it:

var Instance Logger

func CreateLogHandler(path string, fileName string, projectName string) Logger {
    Instance = &LogHandlerSt{
        path: path,
        fileName: fileName,
        projectName: projectName
    }
    fmt.Println("Log files are in \"" + path + "\"")
    return Instance
}

Since only *LogHandlerSt implements Logger, you have to assign a pointer to Instance.

Note that you should rarely (if ever) use a pointer to interface (such as *Logger). Instead the pointer to the concrete type should be wrapped in an interface value.