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.