为什么go函数的定义不同?

I'm trying to learn Go. When I thought that I understand what a function is, how to use it and was looking to get into interfaces I got stuck on this (source Go blog )

package main

import "fmt"

//define a Rectangle struct that has a length and a width
type Rectangle struct { 
   length, width int
}

//write a function Area that can apply to a Rectangle type
func (r Rectangle) Area() int {
   return r.length * r.width
}

func main() {
   r := Rectangle{length:5, width:3} //define a new Rectangle instance with values for its properties
   fmt.Println("Rectangle details are: ",r)  
   fmt.Println("Rectangle's area is: ", r.Area())
}

Why do we have func (r Rectangle) Area() int and not func Area(r Rectangle) int ? Is it any different ?

It is a method as opposed to a function. Generally, you pick and choose which you'd prefer to use (although methods often make more sense when you have number of functions that all act on the same type of object). The only caveat to this is you can only use methods with interfaces. For example:

type Shape interface {
    Area() int
}

type Rectangle struct {
    ...
}

func (r *Rectangle) Area() int {
    ...
}

In this case, to satisfy the Shape interface, Area() must be a method. Having:

func Area(r *Rectangle) int {
    ...
}

would not satisfy the interface.

This means that your function is attached to a type. You can do that for any user-defined type. The difference is how you call the function, instead of using:

a := Area(r);

you will use:

a := r.Area();

This also means that if you define a method like

func (r Rectangle) String() string

Rectangle will automatically implement Stringer, and you will gain the ability to print Rectangle.

They're functionally equivalent in execution, but different in semantics. A function of the form func F(obj T) (in this case func Area(r Rectangle)) is the same thing as writing the code func (obj T) F() (in this case func (r Rectangle) Area()) -- as long as the method body is the same of course.

func (r Rectangle) Area() int {
    return r.length * r.width
}

//...
r.Area()

Is equal to

func Area(r Rectangle) int {
    return r.length * r.width
}
//...
Area(r)

They're equal in the sense that they return the same thing. In fact, if you inspect the function with reflection, you'll find that the method receiver is actually considered the first argument internally. What's not equal is the interface implementation. If you have an interaface

type Areaer interface {
  Area() int
}

(Just roll with the Areaer thing, it's weird but the recommended naming convention). The former implementation will cause Rectangle to implement Area, but the latter won't. Meaning

func PrintArea(a Areaer) {
    fmt.Println(a.Area())
}

When called as PrintArea(r) will work on the first implementation, but not the second.

When to use a free function vs a method is largely a design choice. Generally a method will be ON the attached receiver, while a function will USE the attached receiver. An example is that a Graph may know its successors or nodes, but a function like A* could be a function that takes in a graph.

For the Rectangle, things like Width, Height, Area, Grow, or SetPosition might be good methods because they're things the Rectangle knows about itself (or can do to itself), while a function like Intersects that determines if two rectangles intersect might be a function that takes two rectangles as arguments.

Of course, you'll find plenty of exceptions, either due to bad design or careful consideration. However, I think that's a decent overview of the general state of affairs.