Go: 属性 存在但 Go 编译器说它不存在?
Go: Property exists but Go compiler says it doesn't?
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))
}
我的问题:
我在 运行 进行测试时收到此错误消息:
fileLogger.File.data undefined (type io.Writer has no field or method data)
file.Logger.File
确实属于 type io.Writer
,但是这个字段 data
存在,我知道 Go 是一种强类型语言,所以它不接受这个。
如何解决这个问题?
FileLogger
中的作者 File
是 interface (io.Writer
),而不是 struct
。
您需要 type assertion 才能访问 data
of WriterMock
:
fileLooger.File.(*WriterMock).data
(注意:如果 File 不是 *WriterMock
,那将失败:下面有更多内容)
主要包
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)
}
输出:
Hello, playground '[]'
----
由于类型断言汽车错误,您应该始终检查错误,请考虑“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\n", str)
} else {
fmt.Printf("value is not a string\n")
}
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))
}
我的问题:
我在 运行 进行测试时收到此错误消息:
fileLogger.File.data undefined (type io.Writer has no field or method data)
file.Logger.File
确实属于 type io.Writer
,但是这个字段 data
存在,我知道 Go 是一种强类型语言,所以它不接受这个。
如何解决这个问题?
FileLogger
中的作者 File
是 interface (io.Writer
),而不是 struct
。
您需要 type assertion 才能访问 data
of WriterMock
:
fileLooger.File.(*WriterMock).data
(注意:如果 File 不是 *WriterMock
,那将失败:下面有更多内容)
主要包
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)
}
输出:
Hello, playground '[]'
----
由于类型断言汽车错误,您应该始终检查错误,请考虑“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\n", str)
} else {
fmt.Printf("value is not a string\n")
}