TL,

>From the law (The Go Language Specification) :

Method Sets

The method set of the corresponding pointer type *T is the set of all 
methods declared with receiver *T or T (that is, it also contains the 
method set of T).

Method declarations

The type of a method is the type of a function with the receiver as first 
argument.

Calls

A method call x.m() is valid if the method set of (the type of) x contains 
m and the argument list can be assigned to the parameter list of m. If x is 
addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

In your case:

The argument list can not be assigned to the parameter list of m. The 
method call is invalid.

I don't see how you justify your conclusions. Give specific citations from 
the law (The Go Programming Language Specification) and your interpretation 
of the law which supports your case. Saying it's weird is not enough.

Peter


On Saturday, December 10, 2016 at 5:37:25 AM UTC-5, T L wrote:
>
>
>
> 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 <[email protected]> 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 <[email protected]> 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 [email protected].
>>>>>>> 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 [email protected].
>>>>> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to