LEFT | RIGHT |
1 <!--{ | 1 <!--{ |
2 "Title": "The Laws of Reflection" | 2 "Title": "The Laws of Reflection" |
3 }--> | 3 }--> |
4 <!-- | 4 <!-- |
5 DO NOT EDIT: created by | 5 DO NOT EDIT: created by |
6 tmpltohtml articles/laws_of_reflection.tmpl | 6 tmpltohtml articles/laws_of_reflection.tmpl |
7 --> | 7 --> |
8 | 8 |
9 | 9 |
10 <p> | 10 <p> |
11 Reflection in computing is the | 11 Reflection in computing is the |
12 ability of a program to examine its own structure, particularly | 12 ability of a program to examine its own structure, particularly |
13 through types; it's a form of metaprogramming. It's also a great | 13 through types; it's a form of metaprogramming. It's also a great |
14 source of confusion. | 14 source of confusion. |
15 </p> | 15 </p> |
16 | 16 |
17 <p> | 17 <p> |
18 In this article we attempt to clarify things by explaining how | 18 In this article we attempt to clarify things by explaining how |
19 reflection works in Go. Each language’s reflection model is | 19 reflection works in Go. Each language's reflection model is |
20 different (and many languages don’t support it at all), but | 20 different (and many languages don't support it at all), but |
21 this article is about Go, so for the rest of this article the word | 21 this article is about Go, so for the rest of this article the word |
22 "reflection" should be taken to mean "reflection in Go". | 22 "reflection" should be taken to mean "reflection in Go". |
23 </p> | 23 </p> |
24 | 24 |
25 <p><b>Types and interfaces</b></p> | 25 <p><b>Types and interfaces</b></p> |
26 | 26 |
27 <p> | 27 <p> |
28 Because reflection builds on the type system, let's start with a | 28 Because reflection builds on the type system, let's start with a |
29 refresher about types in Go. | 29 refresher about types in Go. |
30 </p> | 30 </p> |
31 | 31 |
32 <p> | 32 <p> |
33 Go is statically typed. Every variable has a static type, that is, | 33 Go is statically typed. Every variable has a static type, that is, |
34 exactly one type known and fixed at compile time: <code>int</code>, | 34 exactly one type known and fixed at compile time: <code>int</code>, |
35 <code>float32</code>, <code>*MyType</code>, <code>[]byte</code>, | 35 <code>float32</code>, <code>*MyType</code>, <code>[]byte</code>, |
36 and so on. If we declare | 36 and so on. If we declare |
37 </p> | 37 </p> |
38 | 38 |
39 <pre><!--{{code "progs/interface.go" `/type MyInt/` `/STOP/`}} | 39 <pre><!--{{code "progs/interface.go" `/type MyInt/` `/STOP/`}} |
40 -->type MyInt int | 40 -->type MyInt int |
| 41 |
41 var i int | 42 var i int |
42 var j MyInt</pre> | 43 var j MyInt</pre> |
43 | 44 |
44 <p> | 45 <p> |
45 then <code>i</code> has type <code>int</code> and <code>j</code> | 46 then <code>i</code> has type <code>int</code> and <code>j</code> |
46 has type <code>MyInt</code>. The variables <code>i</code> and | 47 has type <code>MyInt</code>. The variables <code>i</code> and |
47 <code>j</code> have distinct static types and, although they have | 48 <code>j</code> have distinct static types and, although they have |
48 the same underlying type, they cannot be assigned to one another | 49 the same underlying type, they cannot be assigned to one another |
49 without a conversion. | 50 without a conversion. |
50 </p> | 51 </p> |
51 | 52 |
52 <p> | 53 <p> |
53 One important category of type is interface types, which represent | 54 One important category of type is interface types, which represent |
54 fixed sets of methods. An interface variable can store any concrete | 55 fixed sets of methods. An interface variable can store any concrete |
55 (non-interface) value as long as that value implements the | 56 (non-interface) value as long as that value implements the |
56 interface’s methods. A well-known pair of examples is | 57 interface's methods. A well-known pair of examples is |
57 <code>io.Reader</code> and <code>io.Writer</code>, the types | 58 <code>io.Reader</code> and <code>io.Writer</code>, the types |
58 <code>Reader</code> and <code>Writer</code> from the <a href= | 59 <code>Reader</code> and <code>Writer</code> from the <a href= |
59 "http://golang.org/pkg/io/">io package</a>: | 60 "http://golang.org/pkg/io/">io package</a>: |
60 </p> | 61 </p> |
61 | 62 |
62 <pre><!--{{code "progs/interface.go" `/// Reader/` `/STOP/`}} | 63 <pre><!--{{code "progs/interface.go" `/// Reader/` `/STOP/`}} |
63 -->// Reader is the interface that wraps the basic Read method. | 64 -->// Reader is the interface that wraps the basic Read method. |
64 type Reader interface { | 65 type Reader interface { |
65 Read(p []byte) (n int, err error) | 66 Read(p []byte) (n int, err error) |
66 } | 67 } |
(...skipping 17 matching lines...) Expand all Loading... |
84 r = os.Stdin | 85 r = os.Stdin |
85 r = bufio.NewReader(r) | 86 r = bufio.NewReader(r) |
86 r = new(bytes.Buffer) | 87 r = new(bytes.Buffer) |
87 // and so on</pre> | 88 // and so on</pre> |
88 | 89 |
89 <p> | 90 <p> |
90 It's important to be clear that whatever concrete value | 91 It's important to be clear that whatever concrete value |
91 <code>r</code> may hold, <code>r</code>'s type is always | 92 <code>r</code> may hold, <code>r</code>'s type is always |
92 <code>io.Reader</code>: Go is statically typed and the static type | 93 <code>io.Reader</code>: Go is statically typed and the static type |
93 of <code>r</code> is <code>io.Reader</code>.</p> | 94 of <code>r</code> is <code>io.Reader</code>.</p> |
| 95 |
| 96 <p> |
94 An extremely important example of an interface type is the empty | 97 An extremely important example of an interface type is the empty |
95 interface: | 98 interface: |
96 </p> | 99 </p> |
97 | 100 |
98 <pre> | 101 <pre> |
99 interface{} | 102 interface{} |
100 </pre> | 103 </pre> |
101 | 104 |
102 <p> | 105 <p> |
103 It represents the empty set of methods and is satisfied by any | 106 It represents the empty set of methods and is satisfied by any |
104 value at all, since any value has zero or more methods.</p> | 107 value at all, since any value has zero or more methods. |
| 108 </p> |
| 109 |
| 110 <p> |
105 Some people say that Go's interfaces are dynamically typed, but | 111 Some people say that Go's interfaces are dynamically typed, but |
106 that is misleading. They are statically typed: a variable of | 112 that is misleading. They are statically typed: a variable of |
107 interface type always has the same static type, and even though at | 113 interface type always has the same static type, and even though at |
108 run time the value stored in the interface variable may change | 114 run time the value stored in the interface variable may change |
109 type, that value will always satisfy the interface.</p> | 115 type, that value will always satisfy the interface. |
| 116 </p> |
| 117 |
| 118 <p> |
110 We need to be precise about all this because reflection and | 119 We need to be precise about all this because reflection and |
111 interfaces are closely related. | 120 interfaces are closely related. |
112 </p> | 121 </p> |
113 | 122 |
114 <p><b>The representation of an interface</b></p> | 123 <p><b>The representation of an interface</b></p> |
115 | 124 |
116 <p> | 125 <p> |
117 Russ Cox has written a <a href= | 126 Russ Cox has written a <a href= |
118 "http://research.swtch.com/2009/12/go-data-structures-interfaces.html"> | 127 "http://research.swtch.com/2009/12/go-data-structures-interfaces.html"> |
119 detailed blog post</a> about the representation of interface values | 128 detailed blog post</a> about the representation of interface values |
120 in Go. It's not necessary to repeat the full story here, but a | 129 in Go. It's not necessary to repeat the full story here, but a |
121 simplified summary is in order. | 130 simplified summary is in order. |
122 </p> | 131 </p> |
123 | 132 |
124 <p> | 133 <p> |
125 A variable of interface type stores a pair: the concrete value | 134 A variable of interface type stores a pair: the concrete value |
126 assigned to the variable, and that value’s type descriptor. | 135 assigned to the variable, and that value's type descriptor. |
127 To be more precise, the value is the underlying concrete data item | 136 To be more precise, the value is the underlying concrete data item |
128 that implements the interface and the type describes the full type | 137 that implements the interface and the type describes the full type |
129 of that item. For instance, after | 138 of that item. For instance, after |
130 </p> | 139 </p> |
131 | 140 |
132 <pre><!--{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}} | 141 <pre><!--{{code "progs/interface.go" `/func typeAssertions/` `/STOP/`}} |
133 --> var r io.Reader | 142 --> var r io.Reader |
134 tty, err = os.OpenFile("/dev/tty", os.O_RDWR, 0) | 143 tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) |
135 if err != nil { return nil, err } | 144 if err != nil { |
| 145 return nil, err |
| 146 } |
136 r = tty</pre> | 147 r = tty</pre> |
137 | 148 |
138 <p> | 149 <p> |
139 <code>r</code> contains, schematically, the (value, type) pair, | 150 <code>r</code> contains, schematically, the (value, type) pair, |
140 (<code>tty</code>, <code>*os.File</code>). Notice that the type | 151 (<code>tty</code>, <code>*os.File</code>). Notice that the type |
141 <code>*os.File</code> implements methods other than | 152 <code>*os.File</code> implements methods other than |
142 <code>Read</code>; even though the interface value provides access | 153 <code>Read</code>; even though the interface value provides access |
143 only to the <code>Read</code> method, the value inside carries all | 154 only to the <code>Read</code> method, the value inside carries all |
144 the type information about that value. That's why we can do things | 155 the type information about that value. That's why we can do things |
145 like this: | 156 like this: |
(...skipping 28 matching lines...) Expand all Loading... |
174 that same pair, (<code>tty</code>, <code>*os.File</code>). That's | 185 that same pair, (<code>tty</code>, <code>*os.File</code>). That's |
175 handy: an empty interface can hold any value and contains all the | 186 handy: an empty interface can hold any value and contains all the |
176 information we could ever need about that value. | 187 information we could ever need about that value. |
177 </p> | 188 </p> |
178 | 189 |
179 <p> | 190 <p> |
180 (We don't need a type assertion here because it's known statically | 191 (We don't need a type assertion here because it's known statically |
181 that <code>w</code> satisfies the empty interface. In the example | 192 that <code>w</code> satisfies the empty interface. In the example |
182 where we moved a value from a <code>Reader</code> to a | 193 where we moved a value from a <code>Reader</code> to a |
183 <code>Writer</code>, we needed to be explicit and use a type | 194 <code>Writer</code>, we needed to be explicit and use a type |
184 assertion because <code>Writer</code>’s methods are not a | 195 assertion because <code>Writer</code>'s methods are not a |
185 subset of <code>Reader</code>’s.)</p> | 196 subset of <code>Reader</code>'s.) |
| 197 </p> |
| 198 |
| 199 <p> |
186 One important detail is that the pair inside an interface always | 200 One important detail is that the pair inside an interface always |
187 has the form (value, concrete type) and cannot have the form | 201 has the form (value, concrete type) and cannot have the form |
188 (value, interface type). Interfaces do not hold interface | 202 (value, interface type). Interfaces do not hold interface |
189 values. | 203 values. |
190 </p> | 204 </p> |
191 | 205 |
192 <p> | 206 <p> |
193 Now we're ready to reflect. | 207 Now we're ready to reflect. |
194 </p> | 208 </p> |
195 | 209 |
196 <p><b>The first law of reflection</b></p> | 210 <p><b>The first law of reflection</b></p> |
| 211 |
197 <p><b>1. Reflection goes from interface value to reflection object.</b></p> | 212 <p><b>1. Reflection goes from interface value to reflection object.</b></p> |
198 | 213 |
199 <p> | 214 <p> |
200 At the basic level, reflection is just a mechanism to examine the | 215 At the basic level, reflection is just a mechanism to examine the |
201 type and value pair stored inside an interface variable. To get | 216 type and value pair stored inside an interface variable. To get |
202 started, there are two types we need to know about in <a href= | 217 started, there are two types we need to know about in |
203 "http://golang.org/pkg/reflect">package reflect</a>: <a href= | 218 <a href="http://golang.org/pkg/reflect">package reflect</a>: |
204 "http://golang.org/pkg/reflect/#Type">Type</a> and <a href= | 219 <a href="http://golang.org/pkg/reflect/#Type">Type</a>and |
205 "http://golang.org/pkg/reflect/#Value">Value</a>. Those two types | 220 <a href="http://golang.org/pkg/reflect/#Value">Value</a>. Those two types |
206 give access to the contents of an interface variable, and two | 221 give access to the contents of an interface variable, and two |
207 simple functions, called <code>reflect.TypeOf</code> and | 222 simple functions, called <code>reflect.TypeOf</code> and |
208 <code>reflect.ValueOf</code>, retrieve <code>reflect.Type</code> | 223 <code>reflect.ValueOf</code>, retrieve <code>reflect.Type</code> |
209 and <code>reflect.Value</code> pieces out of an interface value. | 224 and <code>reflect.Value</code> pieces out of an interface value. |
210 (Also, from the <code>reflect.Value</code> it’s easy to get | 225 (Also, from the <code>reflect.Value</code> it's easy to get |
211 to the <code>reflect.Type</code>, but let’s keep the | 226 to the <code>reflect.Type</code>, but let's keep the |
212 <code>Value</code> and <code>Type</code> concepts separate for | 227 <code>Value</code> and <code>Type</code> concepts separate for |
213 now.) | 228 now.) |
214 </p> | 229 </p> |
215 | 230 |
216 <p> | 231 <p> |
217 Let's start with <code>TypeOf</code>: | 232 Let's start with <code>TypeOf</code>: |
218 </p> | 233 </p> |
219 | 234 |
220 <pre><!--{{code "progs/interface2.go" `/package main/` `/STOP main/`}} | 235 <pre><!--{{code "progs/interface2.go" `/package main/` `/STOP main/`}} |
221 -->package main | 236 -->package main |
222 | 237 |
223 import ( | 238 import ( |
224 "fmt" | 239 "fmt" |
225 "reflect" | 240 "reflect" |
226 ) | 241 ) |
227 | 242 |
228 func main() { | 243 func main() { |
229 var x float64 = 3.4 | 244 var x float64 = 3.4 |
230 fmt.Println("type:", reflect.TypeOf(x)) | 245 fmt.Println("type:", reflect.TypeOf(x)) |
231 }</pre> | 246 }</pre> |
232 | 247 |
233 <p> | 248 <p> |
234 This program prints | 249 This program prints |
235 </p> | 250 </p> |
236 | 251 |
237 <pre> | 252 <pre> |
238 type: float64 | 253 type: float64 |
239 </pre> | 254 </pre> |
240 | 255 |
241 <p> | 256 <p> |
242 You might be wondering where the interface is here, since the | 257 You might be wondering where the interface is here, since the |
243 program looks like it’s passing the <code>float64</code> | 258 program looks like it's passing the <code>float64</code> |
244 variable <code>x</code>, not an interface value, to | 259 variable <code>x</code>, not an interface value, to |
245 <code>reflect.TypeOf</code>. But it's there; as <a href= | 260 <code>reflect.TypeOf</code>. But it's there; as <a href= |
246 "http://golang.org/pkg/reflect/#Type.TypeOf">godoc reports</a>, the | 261 "http://golang.org/pkg/reflect/#Type.TypeOf">godoc reports</a>, the |
247 signature of <code>reflect.TypeOf</code> includes an empty | 262 signature of <code>reflect.TypeOf</code> includes an empty |
248 interface: | 263 interface: |
249 </p> | 264 </p> |
250 | 265 |
251 <pre> | 266 <pre> |
252 // TypeOf returns the reflection Type of the value in the interface{}. | 267 // TypeOf returns the reflection Type of the value in the interface{}. |
253 func TypeOf(i interface{}) Type | 268 func TypeOf(i interface{}) Type |
254 </pre> | 269 </pre> |
255 | 270 |
256 <p> | 271 <p> |
257 When we call <code>reflect.TypeOf(x)</code>, <code>x</code> is | 272 When we call <code>reflect.TypeOf(x)</code>, <code>x</code> is |
258 first stored in an empty interface, which is then passed as the | 273 first stored in an empty interface, which is then passed as the |
259 argument; <code>reflect.TypeOf</code> unpacks that empty interface | 274 argument; <code>reflect.TypeOf</code> unpacks that empty interface |
260 to recover the type information. | 275 to recover the type information. |
261 </p> | 276 </p> |
262 | 277 |
263 <p> | 278 <p> |
264 The <code>reflect.ValueOf</code> function, of course, recovers the | 279 The <code>reflect.ValueOf</code> function, of course, recovers the |
265 value (from here on we'll elide the boilerplate and focus just on | 280 value (from here on we'll elide the boilerplate and focus just on |
266 the executable code): | 281 the executable code): |
267 </p> | 282 </p> |
268 | 283 |
269 <pre><!--{{code "progs/interface2.go" `/var x/` `/STOP/`}} | 284 <pre><!--{{code "progs/interface2.go" `/var x/` `/STOP/`}} |
270 --> var x float64 = 3.4 | 285 --> var x float64 = 3.4 |
271 fmt.Println("type:", reflect.TypeOf(x))</pre> | 286 fmt.Println("type:", reflect.TypeOf(x))</pre> |
272 | 287 |
273 <p> | 288 <p> |
274 prints | 289 prints |
275 </p> | 290 </p> |
276 | 291 |
277 <pre> | 292 <pre> |
278 value: <float64 Value> | 293 value: <float64 Value> |
279 </pre> | 294 </pre> |
280 | 295 |
281 <p> | 296 <p> |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 hold the value: <code>int64</code> for all the signed integers, for | 338 hold the value: <code>int64</code> for all the signed integers, for |
324 instance. That is, the <code>Int</code> method of | 339 instance. That is, the <code>Int</code> method of |
325 <code>Value</code> returns an <code>int64</code> and the | 340 <code>Value</code> returns an <code>int64</code> and the |
326 <code>SetInt</code> value takes an <code>int64</code>; it may be | 341 <code>SetInt</code> value takes an <code>int64</code>; it may be |
327 necessary to convert to the actual type involved: | 342 necessary to convert to the actual type involved: |
328 </p> | 343 </p> |
329 | 344 |
330 <pre><!--{{code "progs/interface2.go" `/START f2/` `/STOP/`}} | 345 <pre><!--{{code "progs/interface2.go" `/START f2/` `/STOP/`}} |
331 --> var x uint8 = 'x' | 346 --> var x uint8 = 'x' |
332 v := reflect.ValueOf(x) | 347 v := reflect.ValueOf(x) |
333 fmt.Println("type:", v.Type()) // uint8. | 348 fmt.Println("type:", v.Type()) // uint8. |
334 fmt.Println("kind is uint8: ", v.Kind() == reflect.Uint8) // true. | 349 fmt.Println("kind is uint8: ", v.Kind() == reflect.Uint8) // true. |
335 x = uint8(v.Uint()) // v.Uint returns a uint64.</pre> | 350 x = uint8(v.Uint()) // v.Uint returns
a uint64.</pre> |
336 | 351 |
337 <p> | 352 <p> |
338 The second property is that the <code>Kind</code> of a reflection | 353 The second property is that the <code>Kind</code> of a reflection |
339 object describes the underlying type, not the static type. If a | 354 object describes the underlying type, not the static type. If a |
340 reflection object contains a value of a user-defined integer type, | 355 reflection object contains a value of a user-defined integer type, |
341 as in | 356 as in |
342 </p> | 357 </p> |
343 | 358 |
344 <pre><!--{{code "progs/interface2.go" `/START f3/` `/START/`}} | 359 <pre><!--{{code "progs/interface2.go" `/START f3/` `/START/`}} |
345 --> type MyInt int | 360 --> type MyInt int |
346 var x MyInt = 7 | 361 var x MyInt = 7 |
347 v := reflect.ValueOf(x)</pre> | 362 v := reflect.ValueOf(x)</pre> |
348 | 363 |
349 <p> | 364 <p> |
350 the <code>Kind</code> of <code>v</code> is still | 365 the <code>Kind</code> of <code>v</code> is still |
351 <code>reflect.Int</code>, even though the static type of | 366 <code>reflect.Int</code>, even though the static type of |
352 <code>x</code> is <code>MyInt</code>, not <code>int</code>. In | 367 <code>x</code> is <code>MyInt</code>, not <code>int</code>. In |
353 other words, the <code>Kind</code> cannot discriminate an int from | 368 other words, the <code>Kind</code> cannot discriminate an int from |
354 a <code>MyInt</code> even though the <code>Type</code> can.</p> | 369 a <code>MyInt</code> even though the <code>Type</code> can. |
355 <p><b>The second law of reflection</b></p></p> | 370 </p> |
| 371 |
| 372 <p><b>The second law of reflection</b></p> |
| 373 |
356 <p><b>2. Reflection goes from reflection object to interface | 374 <p><b>2. Reflection goes from reflection object to interface |
357 value.</b></p></p> | 375 value.</b></p> |
| 376 |
| 377 <p> |
358 Like physical reflection, reflection in Go generates its own | 378 Like physical reflection, reflection in Go generates its own |
359 inverse.</p> | 379 inverse. |
| 380 </p> |
| 381 |
| 382 <p> |
360 Given a <code>reflect.Value</code> we can recover an interface | 383 Given a <code>reflect.Value</code> we can recover an interface |
361 value using the <code>Interface</code> method; in effect the method | 384 value using the <code>Interface</code> method; in effect the method |
362 packs the type and value information back into an interface | 385 packs the type and value information back into an interface |
363 representation and returns the result: | 386 representation and returns the result: |
364 </p> | 387 </p> |
365 | 388 |
366 <pre> | 389 <pre> |
367 // Interface returns v's value as an interface{}. | 390 // Interface returns v's value as an interface{}. |
368 func (v Value) Interface() interface{} | 391 func (v Value) Interface() interface{} |
369 </pre> | 392 </pre> |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 In short, the <code>Interface</code> method is the inverse of the | 447 In short, the <code>Interface</code> method is the inverse of the |
425 <code>ValueOf</code> function, except that its result is always of | 448 <code>ValueOf</code> function, except that its result is always of |
426 static type <code>interface{}</code>. | 449 static type <code>interface{}</code>. |
427 </p> | 450 </p> |
428 | 451 |
429 <p> | 452 <p> |
430 Reiterating: Reflection goes from interface values to reflection | 453 Reiterating: Reflection goes from interface values to reflection |
431 objects and back again. | 454 objects and back again. |
432 </p> | 455 </p> |
433 | 456 |
434 <p><b>The third law of reflection</b></p | 457 <p><b>The third law of reflection</b></p> |
| 458 |
435 <p><b>3. To modify a reflection object, the value must be settable.</b></p> | 459 <p><b>3. To modify a reflection object, the value must be settable.</b></p> |
436 | 460 |
437 <p> | 461 <p> |
438 The third law is the most subtle and confusing, but it's easy | 462 The third law is the most subtle and confusing, but it's easy |
439 enough to understand if we start from first principles. | 463 enough to understand if we start from first principles. |
440 </p> | 464 </p> |
441 | 465 |
442 <p> | 466 <p> |
443 Here is some code that does not work, but is worth studying. | 467 Here is some code that does not work, but is worth studying. |
444 </p> | 468 </p> |
(...skipping 19 matching lines...) Expand all Loading... |
464 </p> | 488 </p> |
465 | 489 |
466 <p> | 490 <p> |
467 The <code>CanSet</code> method of <code>Value</code> reports the | 491 The <code>CanSet</code> method of <code>Value</code> reports the |
468 settability of a <code>Value</code>; in our case, | 492 settability of a <code>Value</code>; in our case, |
469 </p> | 493 </p> |
470 | 494 |
471 <pre><!--{{code "progs/interface2.go" `/START f5/` `/STOP/`}} | 495 <pre><!--{{code "progs/interface2.go" `/START f5/` `/STOP/`}} |
472 --> var x float64 = 3.4 | 496 --> var x float64 = 3.4 |
473 v := reflect.ValueOf(x) | 497 v := reflect.ValueOf(x) |
474 fmt.Println("settability of v:" , v.CanSet())</pre> | 498 fmt.Println("settability of v:", v.CanSet())</pre> |
475 | 499 |
476 <p> | 500 <p> |
477 prints | 501 prints |
478 </p> | 502 </p> |
479 | 503 |
480 <pre> | 504 <pre> |
481 settability of v: false | 505 settability of v: false |
482 </pre> | 506 </pre> |
483 | 507 |
484 <p> | 508 <p> |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 <pre> | 552 <pre> |
529 f(x) | 553 f(x) |
530 </pre> | 554 </pre> |
531 | 555 |
532 <p> | 556 <p> |
533 We would not expect <code>f</code> to be able to modify | 557 We would not expect <code>f</code> to be able to modify |
534 <code>x</code> because we passed a copy of <code>x</code>'s value, | 558 <code>x</code> because we passed a copy of <code>x</code>'s value, |
535 not <code>x</code> itself. If we want <code>f</code> to modify | 559 not <code>x</code> itself. If we want <code>f</code> to modify |
536 <code>x</code> directly we must pass our function the address of | 560 <code>x</code> directly we must pass our function the address of |
537 <code>x</code> (that is, a pointer to <code>x</code>):</p> | 561 <code>x</code> (that is, a pointer to <code>x</code>):</p> |
| 562 |
| 563 <p> |
538 <code>f(&x)</code> | 564 <code>f(&x)</code> |
539 </p> | 565 </p> |
540 | 566 |
541 <p> | 567 <p> |
542 This is straightforward and familiar, and reflection works the same | 568 This is straightforward and familiar, and reflection works the same |
543 way. If we want to modify <code>x</code> by reflection, we must | 569 way. If we want to modify <code>x</code> by reflection, we must |
544 give the reflection library a pointer to the value we want to | 570 give the reflection library a pointer to the value we want to |
545 modify. | 571 modify. |
546 </p> | 572 </p> |
547 | 573 |
548 <p> | 574 <p> |
549 Let’s do that. First we initialize <code>x</code> as usual | 575 Let's do that. First we initialize <code>x</code> as usual |
550 and then create a reflection value that points to it, called | 576 and then create a reflection value that points to it, called |
551 <code>p</code>. | 577 <code>p</code>. |
552 </p> | 578 </p> |
553 | 579 |
554 <pre><!--{{code "progs/interface2.go" `/START f7/` `/START/`}} | 580 <pre><!--{{code "progs/interface2.go" `/START f7/` `/START/`}} |
555 --> var x float64 = 3.4 | 581 --> var x float64 = 3.4 |
556 p := reflect.ValueOf(&x) // Note: take the address of x. | 582 p := reflect.ValueOf(&x) // Note: take the address of x. |
557 fmt.Println("type of p:", p.Type()) | 583 fmt.Println("type of p:", p.Type()) |
558 fmt.Println("settability of p:" , p.CanSet())</pre> | 584 fmt.Println("settability of p:", p.CanSet())</pre> |
559 | 585 |
560 <p> | 586 <p> |
561 The output so far is | 587 The output so far is |
562 </p> | 588 </p> |
563 | 589 |
564 <pre> | 590 <pre> |
565 type of p: *float64 | 591 type of p: *float64 |
566 settability of p: false | 592 settability of p: false |
567 </pre> | 593 </pre> |
568 | 594 |
569 <p> | 595 <p> |
570 The reflection object <code>p</code> isn't settable, but it's not | 596 The reflection object <code>p</code> isn't settable, but it's not |
571 <code>p</code> we want to set, it's (in effect) <code>*p</code>. To | 597 <code>p</code> we want to set, it's (in effect) <code>*p</code>. To |
572 get to what <code>p</code> points to, we call the <code>Elem</code> | 598 get to what <code>p</code> points to, we call the <code>Elem</code> |
573 method of <code>Value</code>, which indirects through the pointer, | 599 method of <code>Value</code>, which indirects through the pointer, |
574 and save the result in a reflection <code>Value</code> called | 600 and save the result in a reflection <code>Value</code> called |
575 <code>v</code>: | 601 <code>v</code>: |
576 </p> | 602 </p> |
577 | 603 |
578 <pre><!--{{code "progs/interface2.go" `/START f7b/` `/START/`}} | 604 <pre><!--{{code "progs/interface2.go" `/START f7b/` `/START/`}} |
579 --> v := p.Elem() | 605 --> v := p.Elem() |
580 fmt.Println("settability of v:" , v.CanSet())</pre> | 606 fmt.Println("settability of v:", v.CanSet())</pre> |
581 | 607 |
582 <p> | 608 <p> |
583 Now <code>v</code> is a settable reflection object, as the output | 609 Now <code>v</code> is a settable reflection object, as the output |
584 demonstrates, | 610 demonstrates, |
585 </p> | 611 </p> |
586 | 612 |
587 <pre> | 613 <pre> |
588 settability of v: true | 614 settability of v: true |
589 </pre> | 615 </pre> |
590 | 616 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 is when using reflection to modify the fields of a structure. As | 650 is when using reflection to modify the fields of a structure. As |
625 long as we have the address of the structure, we can modify its | 651 long as we have the address of the structure, we can modify its |
626 fields. | 652 fields. |
627 </p> | 653 </p> |
628 | 654 |
629 <p> | 655 <p> |
630 Here's a simple example that analyzes a struct value, | 656 Here's a simple example that analyzes a struct value, |
631 <code>t</code>. We create the reflection object with the address of | 657 <code>t</code>. We create the reflection object with the address of |
632 the struct because we'll want to modify it later. Then we set | 658 the struct because we'll want to modify it later. Then we set |
633 <code>typeOfT</code> to its type and iterate over the fields using | 659 <code>typeOfT</code> to its type and iterate over the fields using |
634 straightforward method calls (see <a href= | 660 straightforward method calls (see |
635 "http://golang.org/pkg/reflect/">package reflect</a> for details). | 661 <a href="http://golang.org/pkg/reflect/">package reflect</a> for details). |
636 Note that we extract the names of the fields from the struct type, | 662 Note that we extract the names of the fields from the struct type, |
637 but the fields themselves are regular <code>reflect.Value</code> | 663 but the fields themselves are regular <code>reflect.Value</code> |
638 objects. | 664 objects. |
639 </p> | 665 </p> |
640 | 666 |
641 <pre> | |
642 <pre><!--{{code "progs/interface2.go" `/START f8/` `/STOP/`}} | 667 <pre><!--{{code "progs/interface2.go" `/START f8/` `/STOP/`}} |
643 --> type T struct { | 668 --> type T struct { |
644 A int | 669 A int |
645 B string | 670 B string |
646 } | 671 } |
647 t := T{23, "skidoo"} | 672 t := T{23, "skidoo"} |
648 s := reflect.ValueOf(&t).Elem() | 673 s := reflect.ValueOf(&t).Elem() |
649 typeOfT := s.Type() | 674 typeOfT := s.Type() |
650 for i := 0; i < s.NumField(); i++ { | 675 for i := 0; i < s.NumField(); i++ { |
651 f := s.Field(i) | 676 f := s.Field(i) |
652 fmt.Printf("%d: %s %s = %v\n", i, | 677 fmt.Printf("%d: %s %s = %v\n", i, |
653 typeOfT.Field(i).Name, f.Type(), f.Interface()) | 678 typeOfT.Field(i).Name, f.Type(), f.Interface()) |
654 } | 679 } |
655 s.Field(0).SetInt(77) | 680 s.Field(0).SetInt(77) |
656 s.Field(1).SetString("Sunset Strip") | 681 s.Field(1).SetString("Sunset Strip") |
657 fmt.Println("t is now", t)</pre> | 682 fmt.Println("t is now", t)</pre> |
658 </pre> | |
659 | 683 |
660 <p> | 684 <p> |
661 The output of this program is | 685 The output of this program is |
662 </p> | 686 </p> |
663 | 687 |
664 <pre> | 688 <pre> |
665 0: A int = 23 | 689 0: A int = 23 |
666 1: B string = skidoo | 690 1: B string = skidoo |
667 </pre> | 691 </pre> |
668 | 692 |
669 <p> | 693 <p> |
670 There’s one more point about settability introduced in | 694 There's one more point about settability introduced in |
671 passing here: the field names of <code>T</code> are upper case | 695 passing here: the field names of <code>T</code> are upper case |
672 (exported) because only exported fields of a struct are | 696 (exported) because only exported fields of a struct are |
673 settable.</p> | 697 settable. |
| 698 </p> |
| 699 |
| 700 <p> |
674 Because <code>s</code> contains a settable reflection object, we | 701 Because <code>s</code> contains a settable reflection object, we |
675 can modify the fields of the structure. | 702 can modify the fields of the structure. |
676 </p> | 703 </p> |
677 | 704 |
678 <pre><!--{{code "progs/interface2.go" `/START f8b/` `/STOP/`}} | 705 <pre><!--{{code "progs/interface2.go" `/START f8b/` `/STOP/`}} |
679 --> s.Field(0).SetInt(77) | 706 --> s.Field(0).SetInt(77) |
680 s.Field(1).SetString("Sunset Strip") | 707 s.Field(1).SetString("Sunset Strip") |
681 fmt.Println("t is now", t)</pre> | 708 fmt.Println("t is now", t)</pre> |
682 | 709 |
683 <p> | 710 <p> |
(...skipping 20 matching lines...) Expand all Loading... |
704 <ol> | 731 <ol> |
705 <li>Reflection goes from interface value to reflection | 732 <li>Reflection goes from interface value to reflection |
706 object.</li> | 733 object.</li> |
707 <li>Reflection goes from reflection object to interface | 734 <li>Reflection goes from reflection object to interface |
708 value.</li> | 735 value.</li> |
709 <li>To modify a reflection object, the value must be settable.</li> | 736 <li>To modify a reflection object, the value must be settable.</li> |
710 </ol> | 737 </ol> |
711 | 738 |
712 <p> | 739 <p> |
713 Once you understand these laws reflection in Go becomes much easier | 740 Once you understand these laws reflection in Go becomes much easier |
714 to use, although it remains subtle. It’s a powerful tool that | 741 to use, although it remains subtle. It's a powerful tool that |
715 should be used with care and avoided unless strictly | 742 should be used with care and avoided unless strictly |
716 necessary. | 743 necessary. |
717 </p> | 744 </p> |
718 | 745 |
719 <p> | 746 <p> |
720 There's plenty more to reflection that we haven't covered — | 747 There's plenty more to reflection that we haven't covered — |
721 sending and receiving on channels, allocating memory, using slices | 748 sending and receiving on channels, allocating memory, using slices |
722 and maps, calling methods and functions — but this post is | 749 and maps, calling methods and functions — but this post is |
723 long enough. We'll cover some of those topics in a later | 750 long enough. We'll cover some of those topics in a later |
724 article.</p> | 751 article. |
725 | 752 </p> |
726 <i>By Rob Pike, September 2011</i> | |
LEFT | RIGHT |