douzhoubing2805 2015-03-08 15:42
浏览 33
已采纳

Go:属性存在,但Go编译器说不存在?

filelogger.go

package logger

import (
    "io"
)

type FileLogger struct{
    File io.Writer
}

func NewFileLogger(file io.Writer) *FileLogger{
    return &FileLogger{file}
}

func (this *FileLogger) Log(message string) error {
    _, err := this.File.Write([]byte(appendNewLine(message)))

    return err
}

filelogger_test.go:

package logger

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

type WriterMock struct{
    data []byte
}

func (this WriterMock) Write(b []byte) (n int, err error) {
    this.data = append(this.data, b ...)

    return len(this.data), nil
}

func NewMockedFileLogger() *FileLogger{
    writer := WriterMock{}

    fileLogger := FileLogger{writer}

    return &fileLogger
}

func TestLog(t *testing.T) {
    fileLogger := NewMockedFileLogger()

    fileLogger.Log("Hello World!")

    assert.Equal(t, "Hello World!", string(fileLogger.File.data))
}

My problem:

I'm getting this error message when running go test:

fileLogger.File.data undefined (type io.Writer has no field or method data)

file.Logger.File is indeed of type io.Writer, but this field data exists, I know Go is a strongly typed language, that's why it's not accepting this.

How can solve this?

  • 写回答

1条回答 默认 最新

  • dssj88098 2015-03-08 15:49
    关注

    The writer File in a FileLogger is an interface (io.Writer), not a struct.

    You would need a type assertion in order to access data of WriterMock:

    fileLooger.File.(*WriterMock).data
    

    (Note: that would fail if File was not a *WriterMock: more on that below)


    See this simplified example:

    package main

    import "fmt"
    import "io"
    
    type WriterMock struct {
        data []byte
    }
    
    func (this WriterMock) Write(b []byte) (n int, err error) {
        this.data = append(this.data, b...)
    
        return len(this.data), nil
    }
    
    func main() {
        var w io.Writer = &WriterMock{}
        fmt.Printf("Hello, playground '%+v'", w.(*WriterMock).data)
    }
    

    Output:

    Hello, playground '[]'
    

    ----

    Since a type asertion car error, and you should always check the error, consider the section "Interface conversions and type assertions":

    But if it turns out that the value does not contain a string, the program will crash with a run-time error.
    To guard against that, use the "comma, ok" idiom to test, safely, whether the value is a string:

    str, ok := value.(string)
    if ok {
        fmt.Printf("string value is: %q
    ", str)
    } else {
        fmt.Printf("value is not a string
    ")
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?