-1

Rule is, methods can be defined only on named type and pointer to named type.


For the below code,

package main

type Cat struct {
}

func (c Cat) foo() {
   // do stuff_
}

func (c *Cat) foo() {
  // do stuff_
}

func main() {

}

compiler gives error:

main.go:10: method redeclared: Cat.foo
    method(Cat) func()
    method(*Cat) func()

Above code defines,

method foo() for named type(Cat) and

method foo() for pointer to named type(*Cat).

Question:

For GO compiler, Why methods defined for different type is considered same?

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • With this error, How do I know, what methods to be defined for an allowed type? – overexchange Jan 29 '17 at 23:28
  • 1
    Possible duplicate of [GO - Why implicit non-pointer methods not satisfy interface?](http://stackoverflow.com/questions/41922181/go-why-implicit-non-pointer-methods-not-satisfy-interface) – dev.bmax Jan 29 '17 at 23:29
  • @dev.bmax how do u think it is duplicate? If this query got answer Ed then please share it – overexchange Jan 30 '17 at 01:16
  • 1
    The three threads, that you have started, are all the same. You take one language feature, that just doesn't make sense to you, and you try to find inconsistency in the language methodology. But, the community proves you wrong each time. And finally, you don't accept the answers, that are well supported by documentation and examples, simply because they don't match your intuition. – dev.bmax Jan 30 '17 at 07:30
  • @dev.bmax after seeing your answers, I felt that this is supposed to be my first question. Am not here to accept your answers, instead to learn. – overexchange Jan 30 '17 at 07:33
  • I don't care, who's answer will be accepted. The reason, this thread is marked as a duplicate, is because you are causing people to refrase the same concept over and over again. – dev.bmax Jan 30 '17 at 08:41
  • As other people have already made it clear: the compile time error, that you are getting, means that you are not allowed to confuse the machine, by supplying multiple functions, that are all accessable, using the same statement according to the language rules. If you feel, that the rules are not fair, than SO is not the place to file complains. – dev.bmax Jan 30 '17 at 08:49
  • @dev.bmax rule is given at the very first line of query. Am trying to follow that rule. – overexchange Jan 30 '17 at 15:41

2 Answers2

4

In Go, receivers are a kind of syntactic sugar. The actual, runtime signature of function (c Cat) foo() is foo(c Cat). The receiver is moved to a first parameer.

Go does not support name overloading. There can be only one function of with name foo in a package.

Having said the statements above, you see that there would be two functions named foo with different signatures. This language does not support it.

You cannot do that in Go. The rule of thumb is to write a method for a pointer receiver and Go will use it whenever you have a pointer or value.

If you still need two variants, you need name the methods differently.

Grzegorz Żur
  • 47,257
  • 14
  • 109
  • 105
  • function `foo()` has same signature. In Method `(Cat)foo()` & `(*Cat)foo()`, first parameter is receiver type parameter, which makes different signature. So, how signatures are same? compiler does not complain that function(`foo`) has same signature – overexchange Jan 29 '17 at 23:05
  • @overexchange If you have `var c Cat` and call `c.foo()` how do you disambiguate which method is to be called? – Jonathon Reinhart Jan 29 '17 at 23:09
  • @JonathonReinhart **1)** Are you asking, if GO compiler allows both methods, then, on saying, `var c Cat;c.foo()`, which method to be called? the receiver type `(c Cat)` is suppose to disambiguate. **2)** When I say`func (c*Cat)foo(){..}` am defining method **for** receiver type(`*Cat`) but not for receiver type(`Cat`) and *vice versa* **3)** With this error, Why should I know, which one method I need to define `func (c *Cat)foo(){..}` or `func (c Cat)foo(){..}` because method foo has different signature, with first parameter as one with named type and thesecond as pointer to named type – overexchange Jan 29 '17 at 23:21
-2

For example, you can model some feline behavior like this:

package main

import (
    "fmt"
)

type Growler interface{
    Growl() bool
}

type Cat struct{
    Name string
    Age int
} 

// *Cat is good for both objects and "object references" (pointers to objects)
func (c *Cat) Speak() bool{
    fmt.Println("Meow!")
    return true
}

func (c *Cat) Growl() bool{
    fmt.Println("Grrr!")
    return true
}


func main() {
    var felix Cat // is not a pointer
    felix.Speak() // works :-)
    felix.Growl() // works :-)

    var ginger *Cat = new(Cat) 
    ginger.Speak() // works :-)
    ginger.Growl() // works :-)
}