Skip to content
Newer
Older
100644 61 lines (53 sloc) 2.22 KB
4e71fae @miekg update exercises
authored
1 \begin{Exercise}[title={Method calls},difficulty=2]
37644d7 @miekg forgot to add this one
authored
2 \label{ex:methodcalls}
3 \Question \label{ex:methodcalls q1} Suppose we have the following
d83aa5a @miekg Go1 fixes
authored
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 @miekg forgot to add this one
authored
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 @miekg Go1 fixes
authored
32 above (the Push statements) work correct then?
37644d7 @miekg forgot to add this one
authored
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 @miekg More quoting stuff
authored
44 \Question The answer is given in \cite{go_spec} in the section ``Calls'',
37644d7 @miekg forgot to add this one
authored
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 @miekg small tweaks
authored
57 you too --- now you know this).\footnote{Also see section
dd03ed8 @miekg More quoting stuff
authored
58 ``\titleref{sec:methods}'' in this chapter.}
37644d7 @miekg forgot to add this one
authored
59
60 \end{Answer}
Something went wrong with that request. Please try again.