ruby - ruby 如何区分实例方法和类方法定义?
问题描述
在普通的 ruby 代码中,我通常可以省略self
:
class User
def greeting
# these 2 are the same:
puts "Hi, #{name}"
puts "Hi, #{self.name}"
end
end
但为什么这两个不同:
# 1
class User
def self.greeting
# ...
end
end
# 2
class User
def greeting
# ...
end
end
为什么我不能省略self
?从 ruby 代码编译器的角度来看,这里有什么区别?
我知道#1 是类方法定义(单例方法定义),#2 是实例方法定义。但是 ruby 是如何使用 context 和 self 来实现方法定义的这种差异的呢?
解决方案
在一个方法体中,self
指的是接收者。在下面的第 3..4 行中,一旦确定接收者是一个User
实例(通过def greeting
语法),self
就引用该实例。
class User
def greeting
puts "Hi, #{name}" # method body
puts "Hi, #{self.name}" # method body
end
end
在一个类体中,self
指的是类。在以下第 2、4、8、10 行中,类为User
,因此def self.greeting
与 相同def User.greeting
。
class User
def self.greeting # class body
# ...
end # class body
end
class User
def greeting # class body
# ...
end # class body
end
但我实际上认为你真正的问题不是什么self
意思,而是“一个省略的接收者”在不同的上下文中是什么意思。
在方法调用语法中,省略的接收者代表self
. 所以下面两个是一样的:
name
self.name
在方法定义语法中,省略的接收者代表“类的任何实例”。所以下面两个是不一样的:
def User.greeting; ... end
def greeting; ... end
当你定义一个实例方法时,没有明确的方式来表达“类的任何实例”,所以实际上省略是强制性的。
推荐阅读
- mongodb - Vuejs 使用 Axios 拖动排序项并保存到 mongoDB
- javascript - 带有日期选择器的自动完成框,无需选择日期
- reactjs - 如何在 i18n 中处理不同国家/地区的相同语言?
- javascript - 单击输入标签时反转两种 React 组件文本颜色
- java - 创建 EntityManagerFactory 时出现 ArrayIndexOutOfBoundsException
- javascript - Apache2 + Socket.io 反向代理:正确的方法
- c++ - 如何正确地将 do-loop 转换为 for-loop?
- python - 将 numpy.where 转换为 Linq
- flutter - 如何使用 Flutter MVC 设计模式
- java - 通过枚举休眠查找