miekg/gobook

 4e71fae update exercises miekg authored Jul 22, 2012 1 \begin{Exercise}[title={Method calls},difficulty=2] 37644d7 forgot to add this one miekg authored Aug 15, 2010 2 \label{ex:methodcalls} 3 \Question \label{ex:methodcalls q1} Suppose we have the following d83aa5a Go1 fixes miekg authored May 10, 2012 4 program. Note the package \package{container/vector} was once part 5 of Go, but has been removed when the \func{append} built-in was introduced. 6 However, for this question this isn't important. The package implemented 7 a stack-like structure, with push and pop methods. 37644d7 forgot to add this one miekg authored Aug 15, 2010 8 \begin{lstlisting} 9 package main 10 11 import "container/vector" 12 13 func main() { 14 k1 := vector.IntVector{} 15 k2 := &vector.IntVector{} 16 k3 := new(vector.IntVector) 17 k1.Push(2) 18 k2.Push(3) 19 k3.Push(4) 20 } 21 \end{lstlisting} 22 What are the types of \var{k1}, \var{k2} and \var{k3}? 23 24 \Question Now, this program compiles and runs OK. All the \func{Push} 25 operations work even though the variables are of a different type. The 26 documentation for \func{Push} says: 27 \begin{quote} 28 func (p *IntVector) Push(x int) 29 Push appends x to the end of the vector. 30 \end{quote} 31 So the receiver has to be of type \type{*IntVector}, why does the code d83aa5a Go1 fixes miekg authored May 10, 2012 32 above (the Push statements) work correct then? 37644d7 forgot to add this one miekg authored Aug 15, 2010 33 34 \end{Exercise} 35 36 \begin{Answer} 37 \Question The type of \var{k1} is \type{vector.IntVector}. Why? We use 38 a composite literal (the \verb|{}|), so we get a value of that type 39 back. The variable \var{k2} is of \type{*vector.IntVector}, because we 40 take the address (\verb|&|) of the composite literal. And finally 41 \var{k3} has also the type \type{*vector.IntVector}, because \func{new} 42 returns a pointer to the type. 43 dd03ed8 More quoting stuff miekg authored Mar 10, 2012 44 \Question The answer is given in \cite{go_spec} in the section Calls'', 37644d7 forgot to add this one miekg authored Aug 15, 2010 45 where among other things it says: 46 \begin{quote} 47 A method call \func{x.m()} is valid if the method set of (the type of) 48 \var{x} 49 contains \func{m} and the argument list can be assigned to the parameter list 50 of \func{m}. If \var{x} is addressable and \var{\&x}'s method set 51 contains \func{m}, \func{x.m()} is shorthand for \func{(\&x).m()}. 52 \end{quote} 53 In other words because \var{k1} is addressable and 54 \type{*vector.IntVector} \emph{does} have the \func{Push} method, the 55 call \lstinline{k1.Push(2)} is translated by Go into 56 \lstinline{(&k1).Push(2)} which makes the type system happy again (and a9803a6 small tweaks miekg authored Aug 22, 2010 57 you too --- now you know this).\footnote{Also see section dd03ed8 More quoting stuff miekg authored Mar 10, 2012 58 \titleref{sec:methods}'' in this chapter.} 37644d7 forgot to add this one miekg authored Aug 15, 2010 59 60 \end{Answer}