【发布时间】:2012-12-04 15:34:15
【问题描述】:
谁能向我解释在方法定义中添加self 是什么意思?是不是类似于java中的this关键字?
【问题讨论】:
标签: ruby
谁能向我解释在方法定义中添加self 是什么意思?是不是类似于java中的this关键字?
【问题讨论】:
标签: ruby
与其他语言相反,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。
【讨论】:
Foo 中有def self.bar,那么您可以调用Foo.bar。但是,不同之处在于模块在技术上是Module 类的实例,它是Class 类的实例(即所有类的类)。这与上面 Bernards 回答中的 A 不同,它是“一个类”,它只是 Class 的一个实例。希望这会有所帮助!
在 ruby 中,self 有点类似于 java 中的 this,但是当涉及到类时,它更像是 java 中的关键字 static。一个简短的例子:
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 小时前
【讨论】:
static。特别是,这些方法是动态的,而不是静态的。
self.method ... 定义 Class#method,它有点像 java 中的 class JavaClass; public static void method ...
当声明一个方法时,声明的self 是声明的类/模块,所以实际上你定义了一个类方法。对于客户端,这类似于 java 中的 static 方法。客户端将调用类而不是实例上的方法:MyClass.method
Here你可以找到更多关于类和实例方法的细节。
编辑:虽然self 关键字类似于java 中的this 关键字,但在类方法声明中使用self 的效果类似于在java 中使用static 关键字的效果。相似之处在于 java 中的静态方法,就像 ruby 中的类方法一样,是使用类对象本身而不是类的实例来访问的。
请注意static 不代表动态的反义词。该关键字的名称选择是有问题的(可能继承自 C),而应该称为 perClass 或类似名称以更好地反映含义。技术含义是所有static 成员对于每个类加载器只存在一次。
【讨论】:
static。特别是,这些方法是动态的,而不是静态的。
static——它适用于类级别而不是实例级别。
static 指的是静态绑定(即在编译时确定要调用的方法),而不是用于实例方法的动态绑定。所以从这个意义上说,它确实代表了动态的对立面,但是关键字 static 确实具有不切实际的重载含义,尤其是。在 C 中。