谁能向我解释添加self
到方法定义中的含义是什么?this
和java 中的关键字类似吗?
3 回答
与其他语言相反,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.new
,class A
则重新打开现有类。这就是为什么我们最后有两个单例方法。但在通常情况下,它是类的第一个定义,它意味着Class.new
.
ruby 中的 self 有点类似于this
java 中的,但是当涉及到类时,它更像static
java 中的关键字。一个简短的例子:
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 小时前
声明方法时,self
声明的 是声明类/模块,因此有效地定义了一个类方法。对于客户端,这类似于static
java 中的方法。客户端将调用类而不是实例上的方法:MyClass.method
在这里,您可以找到有关类和实例方法的更多详细信息。
编辑:虽然self
关键字类似于 java 中的this
关键字,但使用self
for 类方法声明的效果类似于static
在 java 中使用关键字的效果。相似之处在于 java 中的静态方法,就像 ruby 中的类方法一样,是使用类对象本身而不是类的实例来访问的。
请注意,static
不代表动态的反义词。该关键字的名称选择是有问题的(可能继承自 C),而是应该被称为perClass
或类似以更好地反映含义。技术含义是每个类加载器的所有static
成员仅存在一次。