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