How does resp.Body implements the Read function? - go

I'm currently studying Go and trying to understand the concept of Interfaces.
What I understand about it is that whatever type implements the functions specified in the interface is part of it.
My question is about the Body of type io.ReadCloser inside of the Response struct. How does it implement the Read function? I've searched through the documentation and couldn't find it.

io.ReadCloser does not implement the Read function. io.ReadCloser is an interface type, so it by itself cannot implement any methods. However, an interface T can implement another interface I if T's type set is a subset of I.
The io.ReadCloser interface embeds the io.Reader and io.Closer interfaces. Therefore the method set of io.ReadeCloser is the combined method set of io.Reader and io.Closer.
Thanks to embedding the type set of io.ReadCloser is the intersection of io.Reader's and io.Closer's type sets. In other words the type set of io.ReadCloser is the set of all types that implement the io.Reader and io.Closer interfaces.
The above also means that the type set of io.ReadCloser is a subset of io.Reader's type set and io.Closer's type set.
The io.ReadCloser interface implements io.Reader because:
A type T implements an interface I if
T is not an interface and is an element of the type set of I; or
T is an interface and the type set of T is a subset of the type set of I.

Related

Can I pass an *io.ReadCloser to a parameter with the type of *io.Reader

I am trying to write a function with a parameter of type *io.Reader
func ReadSomething(r *io.Reader) {
<do something with a reader>
}
but then when I try to pass in a pointer to a reader closer to it
func GetWebPage() {
resp, _ := http.Get(<url>)
ReadSomething(&(resp.Body))
}
I get the following error: cannot use &(resp.Body) (value of type *io.ReadCloser) as *io.Reader value.
This makes no sense to me, a dereferenced pointer to a read closer type should implement the methods of Reader, so why am I not able then to pass it in as an argument to a function that expects a pointer to an io.Reader?
io.ReadCloser is an interface type that is a superset of io.Reader interface type. So whenever an io.Reader is required, you may pass a value of io.ReadCloser.
*io.Reader is not an interface type though, it's a pointer (a pointer to interface), so you can't pass *io.ReadCloser.
Please note that these function signatures are a terrible design. You rarely need a pointer to interface (you'll know when you do, see this for an example). Just use interface types, interfaces may wrap pointers if needed.
It's a common misconception in Go that interfaces are more magical and gluey than they really are. As a starting point, all conversions between distinct types must be explicit, and interfaces are distinct types.
Interfaces only carve out a narrow exception to this rule:
Assignability Rules in the Go Specification (which extends to parameter passing).
A value x is assignable to a variable of type T ("x is assignable to T") if [...]
T is an interface type and x implements T.
Or in other words, simple and plain:
x is assignable to T if x implements T.
That's really the whole entire exception, and it makes no expansive effort to generally mesh interfaces, implementations, and structures thereof. As soon as you indirect your interface value through a pointer, you have stepped out of the enumerated territory.

How to convert multipart.File to io.Reader

Maybe I'm just not understanding how to use the Read method for the File object, but I see in docs that io.Reader is within the multipart.File interface, but I don't understand how to access it. Any guidance would be greatly appreciated.
That means that the multipart.File interface includes the io.Reader interface, so any object that is a valid multipart.File is also a valid io.Reader. Therefore, you can call the Read method (as defined by io.Reader) on an object of type multipart.File.

When using gob to serialiaze structs over the wire, why do we need to Register() any fields that are interfaces inside the transmitted struct?

If we were to send
type ABC struct{
i interface{}
}
gob requires us to register the concrete type hidden behind our interface{}.
Why can't gob use reflection to identify the underlying concrete class in the field by itself.
That is, we need to use the Register method to tell gob what the concrete type is.
Given the method signature looks like this Register(value interface{}), gob already uses reflection to fully identify the type passed to the method.
Why doesn't gob iterate through the instantiated ABC struct at runtime and perform Register automatically?

Why use non-struct types in Golang? [duplicate]

I am actually learning golang (from .NET) and there is one thing I don't understand about this language.
Sometimes I find this kind of declaration:
https://github.com/golang/crypto/blob/master/ed25519/ed25519.go
// PublicKey is the type of Ed25519 public keys.
type PublicKey []byte
What does it mean exactly?
Is it a creating a struct which inherit from []byte?
Is it just an alias?
I thought golang forbid inheritance.
It's a type declaration, more specifically a type definition. It creates a new type, having []byte as its underlying type:
A type definition creates a new, distinct type with the same underlying type and operations as the given type, and binds an identifier to it.
New types are created because they can simplify using them multiple times, their identifier (their name) may be expressive in other contexts, and–most importantly–so that you can define (attach) methods to it (you can't attach methods to built-in types, nor to anonymous types or types defined in other packages).
This last part (attaching methods) is important, because even though instead of attaching methods you could just as easily create and use functions that accept the "original" type as parameter, only types with methods can implement interfaces that list ("prescribe") those methods, and as mentioned earlier, you can't attach methods to certain types unless you create a new type derived from them.
As an example, the type []int will never implement the sort.Interface required to be sortable (by the sort package), so a new type sort.IntSlice is created (which is type IntSlice []int) to which the required methods are attached, so you can pass a value of type sort.IntSlice to the sort.Sort() function but not a value of type []int. Since sort.IntSlice has []int as its underlying type, if you have a value of []int, you can simply convert it to sort.IntSlice if you want to sort it, like in this example (try it on the Go Playground):
is := []int{1,3,2}
sort.Sort(sort.IntSlice(is))
fmt.Println(is) // Prints: [1 2 3]
When you create a new type, there is no "inheritance" involved. The new type will have 0 methods. If you want "inheritance-like" functionality, you should check out embedding (in relation with struct types), in which case the embedder type will also "have" the methods of the embedded type.

How to find types which implement an interface in go

I need an io.Writer for a function. I don't know how to get one from a file...
I know interface are implicit so it complicated the search...
Look at the os.File documentation: it has a func (*File) Write method, which means it is a Writer.
You can use the command guru to list all types implementing an interface.
Notably, the implements query:
The implements query shows interfaces that are implemented by the selected type and, if the selected type is itself an interface, the set of concrete types that implement it.
An implements query on a value reports the same information about the expression’s type.
An implements query on a method shows the set of abstract or concrete methods that are related to it

Resources