Go error: "embedded type cannot be a pointer to interface" - pointers

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?

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.

Related

reflect.Pointer() returned value is not the value address

type BookInfo struct {
Meta *TableMeta
...
}
func (si *schemaInfo) getTabInfo(obj interface{}) (*tabInfo, error) {
typ := reflect.TypeOf(obj)
val := reflect.ValueOf(obj)
if typ.Kind() != reflect.Ptr {
return nil, errors.New("nborm.schemaInfo.getDBInfo() error: required a pointer")
}
meta := *(**TableMeta)(unsafe.Pointer(val.Pointer()))
...
}
getTabInfo() works well, but I want to know why val.Pointer() return a value of **TableMeta? Why not a *TableMeta?The document of reflect says,
Pointer returns v's value as a uintptr. It returns uintptr instead of
unsafe.Pointer so that code using reflect cannot obtain
unsafe.Pointers without importing the unsafe package explicitly. It
panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or
UnsafePointer.
In my mind:
info := &BookInfo{}
val := reflect.ValueOf(info)
ptr := val.Pointer()
meta := (*TableMeta)(unsafe.Pointer(val.Pointer()))
should work, but infact when I called val.Pointer(), the returned value is the pointer of *TableMeta(**TableMeta).
The value you have is a pointer to a BookInfo struct, it is of type *BookInfo. And the type of BookInfo.Meta field is also a pointer, it is of type *TableMeta, thus a *BookInfo can then be looked at as **TableMeta, hence the "double" pointer.
It's true that the struct pointer points to its first field, but don't build on it. It's fragile. If you add a field before it, it'll break badly (which will only happen at runtime, no compile time messages due to package unsafe).
So if the value is of type *BookInfo, simply obtain that out of the reflect.Value wrapper, then you can refer to its field like value.Meta, which will be of type *TableMeta. Avoid using package unsafe, especially if it's not needed.

How does a pointer to a struct or array value in Go work?

Considering the following Go struct:
type Person struct {
Name string
Age int
Country string
}
I have encountered numerious times the following use:
p := &Person{"Adam", 33, "Argentina"}
Yet I can not see the point in pointing to a struct value, and I wonder, how does it differ from:
n := &999 // Error
My questions are:
How is it even possible to point to a value, even if it is a struct or array and not a primitive like a string or int? Strange enough, the following doesn't contribute to my understanding:
fmt.Println(p, &p) // outputs: &{Adam 33 Argentina} 0xc042084018
Why would a programmer want to declare a struct instance by a pointer? What could you achieve doing so?
&Person{} is a language "construct", it's part of the spec: it allocates a new variable of Person type, and provides you the address of that anonymous variable.
Spec: Composite literals:
Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.
Also: Spec: Variables:
Calling the built-in function new or taking the address of a composite literal allocates storage for a variable at run time.
&999 is not allowed by the language spec. The possible operands of the address operators are listed in the Spec: Address operators:
The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
p := Person{} creates a new variable p whose type will be Person. p := &Person{} creates a new variable whose type will be *Person.
See possible duplicate: How do I do a literal *int64 in Go?
When you print the values with the fmt package, it has certain rules how to print values of different types:
For compound objects, the elements are printed using these rules, recursively, laid out like this:
struct: {field0 field1 ...}
array, slice: [elem0 elem1 ...]
maps: map[key1:value1 key2:value2]
pointer to above: &{}, &[], &map[]
When you use fmt.Println(), the default formatting rules will be applied, which for a value of type *int is the %p verb, which will print the memory address in hexadecimal format, but for a pointer to struct it prints the struct value prepended with an & sign (&{}). You can read more about it in related question: Difference between golang pointers
If you want to print the pointed value, dereference the pointer and pass the pointed value, e.g.:
var p = new(int)
*p = 12
fmt.Println(*p) // Prints 12
As to why to create a pointer to a value (and not a value), see these related questions:
Pointers vs. values in parameters and return values
Why should constructor of Go return address?
Go, X does not implement Y (... method has a pointer receiver)

How to invoke a method with pointer receiver after type assertion?

I am learning interface, type conversions and methods with pointer receivers.
The rules and terminology behind pointer receiver methods are confusing to me.
Let me demonstrate my confusion with one program.
This is my Go program.
package main
import "fmt"
type Employee struct {
Name string
}
func (e Employee) Hi() {
fmt.Printf("Hi! I am %s.\n", e.Name)
}
func (e *Employee) Hello() {
fmt.Printf("Hello! I am %s.\n", e.Name)
}
func main() {
var a Employee = Employee{"Alice"}
a.Hi()
a.Hello()
var b interface{} = Employee{"Bob"}
b.(Employee).Hi()
// b.(Employee).Hello()
}
This is the output.
Hi! I am Alice.
Hello! I am Alice.
Hi! I am Bob.
If I remove the last commented out line, I get this error.
# command-line-arguments
./foo.go:24: cannot call pointer method on b.(Employee)
./foo.go:24: cannot take the address of b.(Employee)
How can I fix that line of code so that I am able to invoke the method with
pointer receiver? Please explain a solution with some clarification on why this
does not work by laying down the concepts of methods with pointer receiver.
You can't (in this case implicitly for a pointer receiver) take the address of the result of an expression (b.(Employee)). You can take the address of a variable. For example,
package main
import "fmt"
type Employee struct {
Name string
}
func (e Employee) Hi() {
fmt.Printf("Hi! I am %s.\n", e.Name)
}
func (e *Employee) Hello() {
fmt.Printf("Hello! I am %s.\n", e.Name)
}
func main() {
var a Employee = Employee{"Alice"}
a.Hi()
a.Hello()
var b interface{} = Employee{"Bob"}
b.(Employee).Hi()
// b.(Employee).Hello()
// main.go:24: cannot call pointer method on b.(Employee)
// main.go:24: cannot take the address of b.(Employee)
e := b.(Employee) // e, a variable, is addressable
e.Hello()
var c interface{} = &Employee{"Chris"}
c.(*Employee).Hi()
c.(*Employee).Hello()
}
Output:
Hi! I am Alice.
Hello! I am Alice.
Hi! I am Bob.
Hello! I am Bob.
Hi! I am Chris.
Hello! I am Chris.
The Go Programming Language Specification
Type assertions
For an expression x of interface type and a type T, the primary
expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T.
The notation x.(T) is called a type assertion.
If the type assertion holds, the value of the expression is the value
stored in x and its type is T. If the type assertion is false, a
run-time panic occurs.
Calls
A method call x.m() is valid if the method set of (the type of) x
contains m and the argument list can be assigned to the parameter list
of m. If x is addressable and &x's method set contains m, x.m() is
shorthand for (&x).m()
Address operators
For an operand x of type T, the address operation &x generates a
pointer of type *T to x. The operand must be addressable, that is,
either a variable, pointer indirection, or slice indexing operation;
or a field selector of an addressable struct operand; or an array
indexing operation of an addressable array. As an exception to the
addressability requirement, x may also be a (possibly parenthesized)
composite literal.
The value of the type assertion b.(Employee) is of type Employee. The method call b.(Employee).Hello() is shorthand for (&b.(Employee)).Hello() since func (e *Employee) Hello() has a pointer receiver. But, b.(Employee), an expression, is not addressable. Therefore,
error: cannot call pointer method on b.(Employee)
error: cannot take the address of b.(Employee)
The fix would be:
var b interface{} = &Employee{"Bob"}
b.(*Employee).Hello()
Here b is an interface that is actually a "pointer to Employee" and then same has been type asserted. The thing to remember is that "Employee" and "pointer to Employee" are two different types altogether.

If the type of a parameter is interface{} how do you know whether you pass by pointer or by value?

Given any function that takes a parameter of type interface{} how would I know whether or not to pass that parameter with or without & without navigating the source code of the function.
For example if I had a function with this type signature given to me:
func foo(x interface{}, y int) int
Would there be any way to figure out if x was supposed to be passed by value or by pointer?
Here is the snippet from the source:
// DecodeElement works like Unmarshal except that it takes
// a pointer to the start XML element to decode into v.
// It is useful when a client reads some raw XML tokens itself
// but also wants to defer to Unmarshal for some elements.
func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
val := reflect.ValueOf(v)
if val.Kind() != reflect.Ptr {
return errors.New("non-pointer passed to Unmarshal")
}
return d.unmarshal(val.Elem(), start)
}
It is checking val.Kind() != reflect.Ptr Which means you have to pass the pointer i.e &v.
Its entirely depend on the person who wrote the method or function, so interface{} could be either *ptr or anything but u ve to check that inside your function using reflect.ValueOf(v).Kind() whether the value is a pointer or not and proceeds accordingly.
And little bit about empty interface:
The interface type that specifies zero methods is known as the empty interface:
interface{}
An empty interface may hold values of any type. (Every type implements at least zero methods.)
Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.
Another useful discussion: docs
DecodeElement() and friends have a formal v interface{} whose type is documented in the Unmarshal() function documentation:
Unmarshal parses the XML-encoded data and stores the result in the
value pointed to by v, which must be an arbitrary struct, slice, or
string.
So to literally answer your question, no, you cannot know without reading the source - if the value you want to pass is a struct proper, you need to indirect. If it is already a pointer to that struct, you do not.
For example:
type Result struct {
XMLName xml.Name `xml:"Person"`
Name string `xml:"FullName"`
Phone string
Email []Email
Groups []string `xml:"Group>Value"`
Address
}
var (
a Result
b *Result
c string
)
xmlDecoder.DecodeElement(&a, startElement)
xmlDecoder.DecodeElement(&c, startElement)
but
xmlDecoder.DecodeElement(b, startElement)

Why can't the interface be implemented with pointer receivers

I'm confused as to why this fails to compile with:
impossible type assertion:
Faz does not implement Foo (Bar method has pointer receiver)
if I make the receiver for Faz.Bar a Faz value rather than a Faz pointer then it compiles fine, but I thought it was always better to have pointer receivers so values aren't being copied around?
package main
import (
"log"
)
func main() {
foo := New().(Faz)
log.Println(foo)
}
type Foo interface {
Bar() string
}
func New() Foo {
return &Faz{}
}
type Faz struct {
}
func (f *Faz) Bar() string {
return `Bar`
}
Because it's *Faz not Faz.
func main() {
foo := New().(*Faz)
log.Println(foo)
}
I think the answer to this question needs to a more retrospective approach towards the grammar, and how would implement it through software engineering. (Excuse the over simplification)
First a quick flashback of what are types?
They are just memory blocks with compiler logic on top. What makes an array different from a string is what the compiler allows us to do with those memory blocks. (Think deeper and you may begin to realize the true difference between strongly typed and dynamically typed languages.)
Now next you need to realize that pointers are their own types per say. *variable is a different memory block (aka type) than variable. It's just that the compiler always assumes that content of *variable is always going to be an address to a memory block of type to the right of the declaration along with other restriction/features it imposes.
Then let's recap what an interface is.
Pseudo-scientific definition: A set of requirements for any first class citizen to be of a specific type.
Translated to software engineering- any block of memory (types) that has the same memory structure (think back to structure packing) associated to it as described in a contract (interface) can be passed around as with the type name that the contract mentions.
Now you may begin to realize that when you say
func (f *Faz) Bar() string is f's block of memory holding a function, where f's type is a pointer to Faz
where areas
func (f Faz) Bar() string is f's block of memory, where f's type is Faz
So when you are saying that a variable of *Faz type is satisfying a contract, then how can you assume that a variable of Faz type will qualify as interface type in the code? Chose who satisfies your contract, and only that type can assume the interface type in your code.

Resources