On Saturday, December 10, 2016 at 6:20:00 PM UTC+8, peterGo wrote:
>
> TL,
>
> If you want to be a language lawyer then you must cite the law (The Go 
> Language Specification) to support your argument. For example, perhaps 
> something like this:
>
> From the law:
>
> Method expressions
>
> Consider a struct type T with two methods, Mv, whose receiver is of type 
> T, and Mp, whose receiver is of type *T.
>
>     type T struct {
>         a int
>     }
>     func (tv  T) Mv(a int) int         { return 0 }  // value receiver
>     func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
>
>     var t T
>
> For a method with a value receiver, one can derive a function with an 
> explicit pointer receiver, so
>
>     (*T).Mv
>
> yields a function value representing Mv with signature
>
>     func(tv *T, a int) int
>
> Such a function indirects through the receiver to create a value to pass 
> as the receiver to the underlying method; the method does not overwrite the 
> value whose address is passed in the function call.
>
> In your case:
>
>     type Age int
>
>     func (age Age) CanDrink() bool {
>         age++
>         return age >= 18
>     }
>
>     (*Age).CanDrink
>
> gives
>
>     func(age *Age) bool
>
> From the law:
>
> Calls
>
> Given an expression f of function type F,
>
>     f(a1, a2, … an)
>
> calls f with arguments a1, a2, … an. Except for one special case, 
> arguments must be single-valued expressions assignable to the parameter 
> types of F and are evaluated before the function is called. 
>
> Assignability
>
> A value x is assignable to a variable of type T ("x is assignable to T") 
> in any of these cases:
>
>     x's type is identical to T.
>     x's type V and T have identical underlying types and at least one of V 
> or T is not a named type.
>     T is an interface type and x implements T.
>     x is a bidirectional channel value, T is a channel type, x's type V 
> and T have identical element types, and at least one of V or T is not a 
> named type.
>     x is the predeclared identifier nil and T is a pointer, function, 
> slice, map, channel, or interface type.
>     x is an untyped constant representable by a value of type T.
>
> In your case:
>
> You call function
>
>     func(age *Age) bool
>
> with
>
>     (*Age).CanDrink(age)
>
> By assignment you have types
>
>     *Age = Age
>
> which gives an assignability error
>
>     cannot use age (type Age) as type *Age in argument to (*Age).CanDrink
>
> Peter
>


I know this. 
But the spec says a method M defined for type T is also a method of *T.
In fact, it is not accurate. T.M and (*T).M have different signatures.

 

>
> On Saturday, December 10, 2016 at 4:00:17 AM UTC-5, T L wrote:
>>
>>
>>
>> On Saturday, December 10, 2016 at 4:11:43 PM UTC+8, Axel Wagner wrote:
>>>
>>> On Sat, Dec 10, 2016 at 9:00 AM, T L <tapi...@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> On Saturday, December 10, 2016 at 3:42:34 PM UTC+8, Axel Wagner wrote:
>>>>>
>>>>> I don't understand. You are saying, that you want a method on a 
>>>>> pointer to Age and then find it unreasonable, that you are getting a 
>>>>> method 
>>>>> on a pointer to Age?
>>>>>
>>>>> If you don't want the argument to be a pointer, use Age.CanDrink 
>>>>> instead. Both are valid, because the method set of *Age contains all 
>>>>> methods declared on *Age or on Age (according to the spec 
>>>>> <https://golang.org/ref/spec#Method_sets>).
>>>>>
>>>>
>>>> That is what it is weird, Age.CanDrink and (*Age).CanDrink should be 
>>>> the same function.
>>>>
>>>
>>> Why? Age and *Age are different types. Why would they be interchangeable 
>>> in this case? When the programmer *explicitly* asked for different 
>>> things? That seems like confusing (and infuriating) behavior to me.
>>> You need to come up with a reason why this should be the case, you can't 
>>> simply state that it should.
>>>
>>> I'm sorry, you often make controversial but somewhat valid arguments 
>>> about inconsistencies in go on this list, but this just isn't one of them. 
>>> This is just an unreasonable complaint.
>>>
>>
>> May Go spec is some vague here. 
>>
>> Maybe I should interpret it as following:
>> when a method is defined for a non-interface type and non-pointer named 
>> type T,  
>> a method with the same name is also defined for type *T, implicitly. 
>> The only difference between the signatures of the two methods is they 
>> have different receiver parameter types,   
>> one receiver type is T, the other is type *T.  
>> The implicit method of *T has only one line of code which is a calling of 
>> the corresponding method of T.
>>
>> For this example:
>>
>> type Age int
>> func (age Age) CanDrink() bool {
>>     age++
>>     return age >= 18
>> }
>>
>> // the following method is defined implicitly
>> /*
>> func (age *Age) CanDrink() bool {
>>     return (*age).CanDrink()
>> }
>> */
>>
>>
>>  
>>
>>>
>>>  
>>>
>>>>  
>>>>
>>>>>
>>>>> On Sat, Dec 10, 2016 at 8:17 AM, T L <tapi...@gmail.com> wrote:
>>>>>
>>>>>>
>>>>>> package main
>>>>>>
>>>>>> import "fmt"
>>>>>> import "reflect"
>>>>>>
>>>>>> type Age int
>>>>>> func (age Age) CanDrink() bool {
>>>>>>     age++
>>>>>>     return age >= 18
>>>>>> }
>>>>>>
>>>>>> func main() {
>>>>>>     var age Age = 11
>>>>>>     
>>>>>>     Age.CanDrink(age)
>>>>>>     // (*Age).CanDrink(age) // cannot use age (type Age) as type *Age 
>>>>>> in argument to (*Age).CanDrink
>>>>>>     (*Age).CanDrink(&age)
>>>>>>     fmt.Println(age) // 11
>>>>>>     
>>>>>>     fmt.Println(reflect.TypeOf(Age.CanDrink)) // func(main.Age) bool
>>>>>>     fmt.Println(reflect.TypeOf((*Age).CanDrink)) // func(*main.Age) 
>>>>>> bool
>>>>>> }
>>>>>>
>>>>>> Why is the parameter of (*Age).CanDrink is a pointer? It is not 
>>>>>> reasonable.
>>>>>>
>>>>>> -- 
>>>>>> 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...@googlegroups.com.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>> -- 
>>>> 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...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>

-- 
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