Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1109)

Delta Between Two Patch Sets: doc/articles/laws_of_reflection.html

Issue 5755051: code review 5755051: doc: fix typos in laws_of_reflection article. (Closed)
Left Patch Set: diff -r c1f5756f94b0 https://go.googlecode.com/hg/ Created 13 years, 1 month ago
Right Patch Set: diff -r c1f5756f94b0 https://go.googlecode.com/hg/ Created 13 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | doc/articles/laws_of_reflection.tmpl » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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>
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 fmt.Println(&#34;kind is uint8: &#34;, v.Kind() == reflect.Uint8) // true. 349 fmt.Println(&#34;kind is uint8: &#34;, v.Kind() == reflect.Uint8) // true.
350 x = uint8(v.Uint()) // v.Uint returns a uint64.</pre> 350 x = uint8(v.Uint()) // v.Uint returns a uint64.</pre>
351 351
352 <p> 352 <p>
353 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
354 object describes the underlying type, not the static type. If a 354 object describes the underlying type, not the static type. If a
355 reflection object contains a value of a user-defined integer type, 355 reflection object contains a value of a user-defined integer type,
356 as in 356 as in
357 </p> 357 </p>
358 358
359 <pre><!--{{code "progs/interface2.go" `/START f3/` `/START/`}} 359 <pre><!--{{code "progs/interface2.go" `/START f3/` `/STOP/`}}
360 --> type MyInt int 360 --> type MyInt int
361 var x MyInt = 7 361 var x MyInt = 7
362 v := reflect.ValueOf(x)</pre> 362 v := reflect.ValueOf(x)</pre>
363 363
364 <p> 364 <p>
365 the <code>Kind</code> of <code>v</code> is still 365 the <code>Kind</code> of <code>v</code> is still
366 <code>reflect.Int</code>, even though the static type of 366 <code>reflect.Int</code>, even though the static type of
367 <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
368 other words, the <code>Kind</code> cannot discriminate an int from 368 other words, the <code>Kind</code> cannot discriminate an int from
369 a <code>MyInt</code> even though the <code>Type</code> can. 369 a <code>MyInt</code> even though the <code>Type</code> can.
(...skipping 18 matching lines...) Expand all
388 388
389 <pre> 389 <pre>
390 // Interface returns v's value as an interface{}. 390 // Interface returns v's value as an interface{}.
391 func (v Value) Interface() interface{} 391 func (v Value) Interface() interface{}
392 </pre> 392 </pre>
393 393
394 <p> 394 <p>
395 As a consequence we can say 395 As a consequence we can say
396 </p> 396 </p>
397 397
398 <pre><!--{{code "progs/interface2.go" `/START f3b/` `/START/`}} 398 <pre><!--{{code "progs/interface2.go" `/START f3b/` `/STOP/`}}
399 --> y := v.Interface().(float64) // y will have type float64. 399 --> y := v.Interface().(float64) // y will have type float64.
400 fmt.Println(y)</pre> 400 fmt.Println(y)</pre>
401 401
402 <p> 402 <p>
403 to print the <code>float64</code> value represented by the 403 to print the <code>float64</code> value represented by the
404 reflection object <code>v</code>. 404 reflection object <code>v</code>.
405 </p> 405 </p>
406 406
407 <p> 407 <p>
408 We can do even better, though. The arguments to 408 We can do even better, though. The arguments to
409 <code>fmt.Println</code>, <code>fmt.Printf</code> and so on are all 409 <code>fmt.Println</code>, <code>fmt.Printf</code> and so on are all
410 passed as empty interface values, which are then unpacked by the 410 passed as empty interface values, which are then unpacked by the
411 <code>fmt</code> package internally just as we have been doing in 411 <code>fmt</code> package internally just as we have been doing in
412 the previous examples. Therefore all it takes to print the contents 412 the previous examples. Therefore all it takes to print the contents
413 of a <code>reflect.Value</code> correctly is to pass the result of 413 of a <code>reflect.Value</code> correctly is to pass the result of
414 the <code>Interface</code> method to the formatted print 414 the <code>Interface</code> method to the formatted print
415 routine: 415 routine:
416 </p> 416 </p>
417 417
418 <pre><!--{{code "progs/interface2.go" `/START f3c/` `/START/`}} 418 <pre><!--{{code "progs/interface2.go" `/START f3c/` `/STOP/`}}
419 --> fmt.Println(v.Interface())</pre> 419 --> fmt.Println(v.Interface())</pre>
420 420
421 <p> 421 <p>
422 (Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a 422 (Why not <code>fmt.Println(v)</code>? Because <code>v</code> is a
423 <code>reflect.Value</code>; we want the concrete value it holds.) 423 <code>reflect.Value</code>; we want the concrete value it holds.)
424 Since our value is a <code>float64</code>, we can even use a 424 Since our value is a <code>float64</code>, we can even use a
425 floating-point format if we want: 425 floating-point format if we want:
426 </p> 426 </p>
427 427
428 <pre><!--{{code "progs/interface2.go" `/START f3d/` `/STOP/`}} 428 <pre><!--{{code "progs/interface2.go" `/START f3d/` `/STOP/`}}
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 </p> 511 </p>
512 512
513 <p> 513 <p>
514 Settability is a bit like addressability, but stricter. It's the 514 Settability is a bit like addressability, but stricter. It's the
515 property that a reflection object can modify the actual storage 515 property that a reflection object can modify the actual storage
516 that was used to create the reflection object. Settability is 516 that was used to create the reflection object. Settability is
517 determined by whether the reflection object holds the original 517 determined by whether the reflection object holds the original
518 item. When we say 518 item. When we say
519 </p> 519 </p>
520 520
521 <pre><!--{{code "progs/interface2.go" `/START f6/` `/START/`}} 521 <pre><!--{{code "progs/interface2.go" `/START f6/` `/STOP/`}}
522 --> var x float64 = 3.4 522 --> var x float64 = 3.4
523 v := reflect.ValueOf(x)</pre> 523 v := reflect.ValueOf(x)</pre>
524 524
525 <p> 525 <p>
526 we pass a <em>copy</em> of <code>x</code> to 526 we pass a <em>copy</em> of <code>x</code> to
527 <code>reflect.ValueOf</code>, so the interface value created as the 527 <code>reflect.ValueOf</code>, so the interface value created as the
528 argument to <code>reflect.ValueOf</code> is a <em>copy</em> of 528 argument to <code>reflect.ValueOf</code> is a <em>copy</em> of
529 <code>x</code>, not <code>x</code> itself. Thus, if the 529 <code>x</code>, not <code>x</code> itself. Thus, if the
530 statement 530 statement
531 </p> 531 </p>
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 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
571 modify. 571 modify.
572 </p> 572 </p>
573 573
574 <p> 574 <p>
575 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
576 and then create a reflection value that points to it, called 576 and then create a reflection value that points to it, called
577 <code>p</code>. 577 <code>p</code>.
578 </p> 578 </p>
579 579
580 <pre><!--{{code "progs/interface2.go" `/START f7/` `/START/`}} 580 <pre><!--{{code "progs/interface2.go" `/START f7/` `/STOP/`}}
581 --> var x float64 = 3.4 581 --> var x float64 = 3.4
582 p := reflect.ValueOf(&amp;x) // Note: take the address of x. 582 p := reflect.ValueOf(&amp;x) // Note: take the address of x.
583 fmt.Println(&#34;type of p:&#34;, p.Type()) 583 fmt.Println(&#34;type of p:&#34;, p.Type())
584 fmt.Println(&#34;settability of p:&#34;, p.CanSet())</pre> 584 fmt.Println(&#34;settability of p:&#34;, p.CanSet())</pre>
585 585
586 <p> 586 <p>
587 The output so far is 587 The output so far is
588 </p> 588 </p>
589 589
590 <pre> 590 <pre>
591 type of p: *float64 591 type of p: *float64
592 settability of p: false 592 settability of p: false
593 </pre> 593 </pre>
594 594
595 <p> 595 <p>
596 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
597 <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
598 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>
599 method of <code>Value</code>, which indirects through the pointer, 599 method of <code>Value</code>, which indirects through the pointer,
600 and save the result in a reflection <code>Value</code> called 600 and save the result in a reflection <code>Value</code> called
601 <code>v</code>: 601 <code>v</code>:
602 </p> 602 </p>
603 603
604 <pre><!--{{code "progs/interface2.go" `/START f7b/` `/START/`}} 604 <pre><!--{{code "progs/interface2.go" `/START f7b/` `/STOP/`}}
605 --> v := p.Elem() 605 --> v := p.Elem()
606 fmt.Println(&#34;settability of v:&#34;, v.CanSet())</pre> 606 fmt.Println(&#34;settability of v:&#34;, v.CanSet())</pre>
607 607
608 <p> 608 <p>
609 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
610 demonstrates, 610 demonstrates,
611 </p> 611 </p>
612 612
613 <pre> 613 <pre>
614 settability of v: true 614 settability of v: true
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 <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
658 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
659 <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
660 straightforward method calls (see· 660 straightforward method calls (see·
661 <a href="http://golang.org/pkg/reflect/">package reflect</a> for details). 661 <a href="http://golang.org/pkg/reflect/">package reflect</a> for details).
662 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,
663 but the fields themselves are regular <code>reflect.Value</code> 663 but the fields themselves are regular <code>reflect.Value</code>
664 objects. 664 objects.
665 </p> 665 </p>
666 666
667 <pre><!--{{code "progs/interface2.go" `/START f8/` `/START/`}} 667 <pre><!--{{code "progs/interface2.go" `/START f8/` `/STOP/`}}
668 --> type T struct { 668 --> type T struct {
669 A int 669 A int
670 B string 670 B string
671 } 671 }
672 t := T{23, &#34;skidoo&#34;} 672 t := T{23, &#34;skidoo&#34;}
673 s := reflect.ValueOf(&amp;t).Elem() 673 s := reflect.ValueOf(&amp;t).Elem()
674 typeOfT := s.Type() 674 typeOfT := s.Type()
675 for i := 0; i &lt; s.NumField(); i++ { 675 for i := 0; i &lt; s.NumField(); i++ {
676 f := s.Field(i) 676 f := s.Field(i)
677 fmt.Printf(&#34;%d: %s %s = %v\n&#34;, i, 677 fmt.Printf(&#34;%d: %s %s = %v\n&#34;, i,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 necessary. 740 necessary.
741 </p> 741 </p>
742 742
743 <p> 743 <p>
744 There's plenty more to reflection that we haven't covered &mdash; 744 There's plenty more to reflection that we haven't covered &mdash;
745 sending and receiving on channels, allocating memory, using slices 745 sending and receiving on channels, allocating memory, using slices
746 and maps, calling methods and functions &mdash; but this post is 746 and maps, calling methods and functions &mdash; but this post is
747 long enough. We'll cover some of those topics in a later 747 long enough. We'll cover some of those topics in a later
748 article. 748 article.
749 </p> 749 </p>
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b