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.