首页 > 解决方案 > 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 来实现方法定义的这种差异的呢?

标签: ruby

解决方案


在一个方法体中,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

当你定义一个实例方法时,没有明确的方式来表达“类的任何实例”,所以实际上省略是强制性的。


推荐阅读