76

谁能向我解释添加self到方法定义中的含义是什么?this和java 中的关键字类似吗?

4

3 回答 3

101

与其他语言相反,Ruby 没有类方法,但它具有附加到特定对象的单例方法。

cat = String.new("cat")
def cat.speak
    'miaow'
end
cat.speak #=> "miaow" 
cat.singleton_methods #=> ["speak"] 

def cat.speak创建一个附加到对象 cat 的单例方法。

当你写的时候class A,它相当于A = Class.new

A = Class.new
def A.speak
    "I'm class A"
end
A.speak #=> "I'm class A" 
A.singleton_methods #=> ["speak"] 

def A.speak创建一个附加到对象 A 的单例方法。我们称它为类 A 的类方法。

当你写

class A
    def self.c_method
        'in A#c_method'
    end
end

您创建Class(*) 的一个实例。在类定义中,Ruby 将 self 设置为这个新的 Class 实例,该实例已分配给常量 A。因此def self.c_method等价于def cat.speak,也就是说您定义了一个附加到对象 self 的单例方法,该对象当前是类 A .

现在类 A 有两个单例方法,我们通常称之为类方法。

A.singleton_methods
 => ["c_method", "speak"] 

(*) 从技术上讲,在这种情况下,如果A已经创建A = Class.newclass A则重新打开现有类。这就是为什么我们最后有两个单例方法。但在通常情况下,它是类的第一个定义,它意味着Class.new.

于 2012-12-04T18:53:55.113 回答
60

ruby 中的 self 有点类似于thisjava 中的,但是当涉及到类时,它更像staticjava 中的关键字。一个简短的例子:

class A 
  # class method 
  def self.c_method
    true
  end
  # instance method
  def i_method
    true
  end
end

A.c_method #=> true
A.i_method #=> failure
A.new.i_method #=> true
A.new.c_method #=> failure

更新: java中的静态方法和ruby中的类方法之间的区别

Java 中的静态方法有两个不同的特点,使它们与实例方法不同:a) 它们是静态的,b) 它们与实例无关。(IOW:它们根本不像方法,它们只是过程。)在 Ruby 中,所有方法都是动态的,并且所有方法都与一个实例相关联。事实上,与 Java 中存在三种不同的“方法”(实例方法、静态方法和构造函数)不同,Ruby 中只有一种方法:实例方法。所以,不:Java 中的静态方法与 Ruby 中的方法完全不同。– Jörg W Mittag 1 小时前

于 2012-12-04T15:40:51.707 回答
13

声明方法时,self声明的 是声明类/模块,因此有效地定义了一个类方法。对于客户端,这类似于staticjava 中的方法。客户端将调用类而不是实例上的方法:MyClass.method

在这里,您可以找到有关类和实例方法的更多详细信息。

编辑:虽然self关键字类似于 java 中的this关键字,但使用selffor 类方法声明的效果类似于static在 java 中使用关键字的效果。相似之处在于 java 中的静态方法,就像 ruby​​ 中的类方法一样,是使用类对象本身而不是类的实例来访问的。

请注意,static不代表动态的反义词。该关键字的名称选择是有问题的(可能继承自 C),而是应该被称为perClass或类似以更好地反映含义。技术含义是每个类加载器的所有static成员仅存在一次。

于 2012-12-04T15:35:45.530 回答