Thanks Dave&TL, I understand constant values and literal values are not 
addressable, from the reference link (
http://www.tapirgames.com/blog/golang-summaries#not-addressable 
<http://www.google.com/url?q=http%3A%2F%2Fwww.tapirgames.com%2Fblog%2Fgolang-summaries%23not-addressable&sa=D&sntz=1&usg=AFQjCNGrIgDZyKGjv_hUm-F4xYtIuKV6kQ>)
 
given by TL there are many other cases in which compiler are not able to 
get the address of value, is there any explanation about why these value 
are not addressable (e.g. bytes in strings)? thanks.

Values that can't be taken addresses
Following values can't be taken addresses: 
   
   - bytes in strings
   - map elements
   - dynamic values of interface values (exposed by type assertions)
   - constant values
   - literal values
   - package level functions
   - methods (used as function values)
   - intermediate values 
      - function calls
      - explicit value conversions
      - all sorts of operations, except pointer dereference operations, but 
      including: 
         - channel receive operations
         - sub-string operations
         - sub-slice operations
         - addition, subtraction, multiplication, and division, etc.
      
Please note, there is a syntax sugar, &T{}, in Golang. It is a short form 
of 
tmp := T{}; (&tmp) 
so &T{} is legal doesn't mean T{} is addressable. 

BTW, following values can be taken addresses: 
   
   - variables
   - fields of addressable structs
   - elements of addressable arrays
   - elements of any slices (whether the slices are addressable or not)
   - pointer dereference operations

Regards,
Peng

在 2017年7月7日星期五 UTC+8上午9:44:55,Dave Cheney写道:
>
> This is a really interesting corner case of the syntactic sugar of the 
> language.
>
> The first piece of sugar is that methods are just functions with a 
> predefined first parameter, or to say that another way, a method is just a 
> function with the receiver as it's first parameter. So
>
> func (t *T) Foo() becomes Foo(t *T) 
>
> The second piece of sugar is automatically taking the address of, or 
> dereferencing, the receiver depending on the type required. For example
>
> type T struct { }
>
> func (t *T) Foo() {}
>
> func main() {
>     var t T
>     t.Foo()
> }
>
> Foo is defined on *T, but inside main that method is invoked on a value of 
> type T, so behind the scenes the compiler does this
>
>     (&t).Foo()
>
> It takes the address of t, and passes that, as the first argument to Foo, 
> as the receiver.
>
> In your example, even if you could define a method on a type that you 
> didn't define, int, everyone knows that you cannot take the address of a 
> constant literal;
>
> &42.F00() // doesn't work
>
> So, the question is, by converting the untyped integer literal 42 to a 
> duration, why doesn't that work; or to be specific why does it only work 
> when `pretty` is defined on a duration, not a *duration? The easiest way to 
> explain it would be this
>
> func main() {
>      const d = duration(42)
>      d.pretty()
> }
>
> Hopefully you agree that this is the same as your example on line 17, and 
> that this makes it clear that to dispatch to d's pretty method the compiler 
> would have to take the address of d. And as d is a constant, not a 
> variable, this is not permitted as constants are not addressable.
>
> Thanks
>
> Dave
>
> On Thursday, 6 July 2017 22:09:45 UTC+10, Peng wrote:
>>
>> Hi, 
>> In the chapter of "Method set" from "Go in Action", there is a 
>> description as below "This shows that it’s not always possible to get the 
>> address of a value.", the question is in which case does compiler not able 
>> to get the address of a value and why, thanks.
>>
>> 01 // Sample program to show how you can't always get the
>> 02 // address of a value.
>> 03 package main
>> 04
>> 05 import "fmt"
>> 06
>> 07 // duration is a type with a base type of int.
>> 08 type duration int
>> 09
>> 10 // format pretty-prints the duration value.
>> 11 func (d *duration) pretty() string {
>> 12 return fmt.Sprintf("Duration: %d", *d)
>> 13 }
>> 14
>> 15 // main is the entry point for the application.
>> 16 func main() {
>> 17 duration(42).pretty()
>> 18
>> 19 // ./listing46.go:17: cannot call pointer method on duration(42)
>> 20 // ./listing46.go:17: cannot take the address of duration(42)
>> 21 }
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to