如何理解go中的函数与方法
如何理解这句话
方法是与对象实例绑定的特殊函数。
方法是面向对象编程的基本概念,用于维护和展示对象的自身状态。对象是内敛的,每
个实例都有各自不同的独立特征,以属性和方法来暴露对外通信接口。普通函数则专注
于算法流程,通过接收参数来完成特定逻辑运算,并返回最终结果。换句话说,方法是
有关联状态的,而函数通常没有。
方法和函数定义语法区别的在于前者有前置实例接收参数(receiver),编译器以此确定
方法所属类型。在某些语言里,尽管没有显式定义,但会在调用时隐式传递s实例参数。
这段话从概念和语法两个层面对比了方法(method)和函数(function),并将其放在面向对象编程(OOP)的背景下进行解释。让我逐步拆解并帮你理解这句话的含义。
1. “方法是与对象实例绑定的特殊函数”
含义
- 方法:方法是一种特殊的函数,它与某个对象(实例)关联在一起。换句话说,方法是“属于”某个对象的。
- 对象实例:在 OOP 中,对象是类的实例化结果,每个对象都有自己的状态(属性)和行为(方法)。
- 绑定:方法通常需要操作对象的状态,因此它与对象绑定在一起,调用时会作用于特定的实例。
示例(Go 语言)
type Person struct {
Name string
}
func (p Person) Say() string { // 方法,绑定到 Person 类型
return "Hello, " + p.Name
}
func main() {
p := Person{Name: "Tom"}
fmt.Println(p.Say()) // 调用方法,输出 "Hello, Tom"
}
Say是Person类型的方法,与实例p绑定,访问p.Name。
对比普通函数
func say(name string) string { // 普通函数
return "Hello, " + name
}
say是一个独立函数,不绑定任何对象,纯粹通过参数name操作。
2. “方法是面向对象编程的基本概念,用于维护和展示对象的自身状态”
含义
- 基本概念:在 OOP 中,方法是对象行为的核心表达方式。
- 维护和展示状态:方法的主要作用是操作对象的内部数据(属性),或者向外界展示对象的状态。
- 例子:一个
Person对象可能有Name属性,方法Say可以展示这个状态,方法SetName可以修改它。
示例
func (p *Person) SetName(name string) { // 修改状态
p.Name = name
}
SetName方法维护了p的状态(Name属性)。
3. “对象是内敛的,每个实例都有各自不同的独立特征,以属性和方法来暴露对外通信接口”
含义
- 内敛的:对象的状态(属性)通常是私有或受控的,不会随意暴露。
- 独立特征:每个对象实例都有自己的属性值,例如两个
Person实例可以有不同的Name。 - 对外通信接口:对象通过属性(有时直接访问)和方法与外界交互,方法是主要的交互方式。
示例
p1 := Person{Name: "Tom"}
p2 := Person{Name: "Alice"}
fmt.Println(p1.Say()) // "Hello, Tom"
fmt.Println(p2.Say()) // "Hello, Alice"
p1和p2是独立的实例,各自有不同的Name,通过Say方法展示。
4. “普通函数则专注于算法流程,通过接收参数来完成特定逻辑运算,并返回最终结果”
含义
- 普通函数:不像方法那样与对象绑定,函数更关注独立的任务或算法。
- 参数和返回:函数通过输入参数执行逻辑,输出结果,不依赖任何对象的状态。
示例
func add(a, b int) int { // 普通函数
return a + b
}
add只关心输入a和b,计算并返回结果,没有状态关联。
5. “换句话说,方法是有关联状态的,而函数通常没有”
含义
- 方法的状态关联:方法通常操作对象的属性(状态),依赖于实例的上下文。
- 函数的无状态性:函数不绑定对象,通常是“纯函数”,只依赖输入,不涉及外部状态。
对比
- 方法:
p.Say()依赖p.Name,有状态。 - 函数:
say("Tom")不依赖任何对象状态,只依赖参数。
6. “方法和函数定义语法区别的在于前者有前置实例接收参数 (receiver),编译器以此确定方法所属类型”
含义
- 接收者(receiver):在 Go 中,方法定义时有一个显式的接收者参数,指定方法绑定到的类型。
- 语法区别:
- 函数:
func name(params) returnType - 方法:
func (receiver Type) name(params) returnType
- 函数:
- 编译器作用:接收者告诉编译器这个方法属于哪个类型。
示例(Go)
func (p Person) Say() string { // 方法,接收者是 p,类型是 Person
return "Hello, " + p.Name
}
func say(name string) string { // 函数,无接收者
return "Hello, " + name
}
p是接收者,Say属于Person类型。
7. “在某些语言里,尽管没有显式定义,但会在调用时隐式传递实例参数”
含义
- 隐式传递:在一些语言(如 Python、JavaScript)中,方法调用时会隐式传递实例(通常称为
self或this),不需要显式声明接收者。 - 与 Go 的区别:Go 要求显式定义接收者,而其他语言可能在底层自动处理。
示例(Python)
class Person:
def __init__(self, name):
self.name = name
def say(self): # 隐式传递 self
return "Hello, " + self.name
p = Person("Tom")
print(p.say()) # 输出 "Hello, Tom"
self是隐式传递的,等价于 Go 的显式接收者p。
Go 的显式性
- Go 中必须写
(p Person),强制显式绑定,体现了 Go 的简单和透明哲学。
如何整体理解这句话?
核心思想
- 方法 vs 函数:
- 方法是面向对象的一部分,与对象实例绑定,关注状态的管理和行为。
- 函数是独立的,关注算法和逻辑,无状态关联。
- OOP 中的方法:
- 方法是对象与外界交互的接口,依赖于对象的属性。
- 每个实例有独立状态,方法操作这些状态。
- 语法的体现:
- 方法通过接收者(receiver)绑定类型,Go 显式定义,其他语言可能隐式传递。
用类比理解
- 方法:就像某个人的“说话”能力,依赖于这个人的名字(状态),每个人说的话不同。
- 函数:就像一个计算器,只管输入数字,算出结果,不关心是谁在用它。
Go 的视角
- Go 的方法设计体现了其“轻量面向对象”哲学:通过接收者绑定方法,通过接口实现多态,但避免了传统 OOP 的复杂继承体系。
总结
- 概念上:方法是有状态的,函数是无状态的;方法服务于对象,函数服务于逻辑。
- 语法上:方法有接收者(显式或隐式),函数没有。
- 实践中:在 Go 中,方法通过
(receiver Type)绑定对象,其他语言可能隐式处理(如 Python 的self)。
如果你对某个部分还有疑问,或者想深入某一点(比如 Go 的接收者 vs Python 的 self),随时告诉我!

浙公网安备 33010602011771号