On Saturday, December 10, 2016 at 7:27:24 PM UTC+8, peterGo wrote:
>
> 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.
>


"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)."
"The type of a method is the type of a function with the receiver as first 
argument."

Yes, the confusion comes from the two combined. The two imply T.M and 
(*T).M are the same method, and T.M and (*T).M have the same receiver 
parameter.
In fact, not.


 

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