2

The following code gives compile-time error:

type IFile interface {
    Read() (n int, err error)
    Write() (n int, err error)
}

type TestFile struct {
   *IFile
}

Error:

./test.go:18: embedded type cannot be a pointer to interface

Why can't I embed *IFile?

1
  • Because it is forbidden. Commented Nov 9, 2016 at 9:57

1 Answer 1

5

The language spec does not allow it. Relevant section from the spec: Struct types:

A field declared with a type but no explicit field name is an anonymous field, also called an embedded field or an embedding of the type in the struct. An embedded type must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.

A pointer to an interface type is very rarely useful, as an interface type may hold a pointer or a non-pointer value.

Having said that, if a concrete type that implements your IFile type is a pointer type, then a pointer value will be wrapped in an interface value of type IFile, so you still have to embed IFile, just the value that implements IFile will be a pointer value, e.g.

// Let's say *FileImpl implements IFile:
f := TestFile{IFile: &FileImpl{}}

Edit: Answer to your comment:

First, this is Go, not C++. In Go, interfaces are not pointers, but they are represented as a pair of (type;value), where "value" may be pointer or non-pointer. More about this in blog post: The Laws of Reflection: The representation of an interface.

Second, if FileImpl is a type, f := TestFile{IFile : &FileIml} is obviously a compile-time error, you need a value of *FileImpl and &FileImpl clearly isn't. You need for example a composite literal which is in the form of &FileImpl{}, so it should be as I posted above.

Sign up to request clarification or add additional context in comments.

3 Comments

type IFile interface { Read() (n int, err error) Write() (n int, err error) } type FileImp { string file_name ..... } type TestFile struct { IFile } f := TestFile{IFile : FileIml} Does f contains FileImp field's memory copy ?
@sotter The f.IFile field is an interface type, it contains the copy of FileImpl, so yes, f contains a copy of FileImpl. If you don't want that, use a poitner, e.g. &FileImpl, so only a copy of the pointer will be stored, but it will point to the same FileImpl value.
thanks , I understand that, however, ` f := TestFile{IFile : &FileIml}` can not build. In c++, Interface is a Pointer, that's why i want to type TestFile struct { *IFile} in golang.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.