Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason golang discriminates method sets on T and *T?

Tags:

methods

go

This is where confuses me the most while learning go. We all know that methods on T only affect the copy of T, and methods on *T will affect the actual data on T.

Why does methods on T can also be used by *T, but the opposite is not allowed? So,can you give me an example(or reason) on why they do not allow method on *T be used by T?

What is the pros and cons of this design?

like image 833
Dew Avatar asked Apr 13 '14 15:04

Dew


People also ask

What is method set Golang?

The method set is the collection of functions associated with that type as methods and used by the Go compiler to determine whether some type can be assigned to a variable with an interface type.

How a variable type is checked at runtime in Go language?

A quick way to check the type of a value in Go is by using the %T verb in conjunction with fmt. Printf . This works well if you want to print the type to the console for debugging purposes.

What is a method Golang?

A method is a function with a special receiver argument. The receiver appears in its own argument list between the func keyword and the method name. In this example, the Abs method has a receiver of type Vertex named v . < 1/26 > methods.go Syntax Imports.


1 Answers

There are many answers here, but non of them answer why this is the case.

First lets take the case of you having a *T and wanting to call a method which takes T. To do this, all you need to do is pass *yourT (where * is being used to dereference the pointer) to the function. This is guaranteed to be possible because you are just copying blob of memory at a known location.

Now lets say you have a T and want a *T. You may be thinking that you could just do &yourT and get its address. But life isn't always so simple. There isn't always a static address to take.


From the spec:

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.

You may be asking yourself why they would place these arbitrary restrictions on getting a memory address. Every variable must have some memory address, right? While this is true, optimizations can make those addresses rather ephemeral.

For example, lets say the variable was inside a map:

res := TMap["key"].pointerMethod()

In this case, you are effectively saying you want a pointer to memory being held inside a map. This would force every implementation of Go to implement map in such a way that memory addresses remain static. This would severely limit the internal structures of the runtime and give the implementers much less freedom in building an efficient map.

There are other examples such as function returns or interfaces, but you only need one example to prove that the operation is not guaranteed to be possible.


The bottom line is that computer memory isn't simple and while you may want to say "just take the address", it isn't always that simple. Taking an address that is guaranteed to be static isn't always possible. Therefore, you can't guarantee that any instance of T may be turned into a pointer and passed to a pointer method.

like image 193
Stephen Weinberg Avatar answered Oct 05 '22 20:10

Stephen Weinberg