def`self.function`这个名字是什么意思?

Dud*_*ude 59 ruby

任何人都可以向我解释添加self到方法定义的重要性是什么?它与thisjava中的关键字类似吗?

Ber*_*rdK 80

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

cat = String.new("cat")
def cat.speak
    'miaow'
end
cat.speak #=> "miaow" 
cat.singleton_methods #=> ["speak"] 
Run Code Online (Sandbox Code Playgroud)

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"] 
Run Code Online (Sandbox Code Playgroud)

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

当你写作

class A
    def self.c_method
        'in A#c_method'
    end
end
Run Code Online (Sandbox Code Playgroud)

您创建一个Class(*)的实例.在类定义中,Ruby将self设置为这个新的Class实例,它已被赋值给常量A.因此Class相当于def self.c_method,也就是说你定义了一个附加到对象self的单例方法,它当前是A类.

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

A.singleton_methods
 => ["c_method", "speak"] 
Run Code Online (Sandbox Code Playgroud)

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

  • 这是正确的答案.确实,经验丰富的Rubyists有时会使用术语"类方法"来表示"类对象的单例类的实例方法",但它们只是在完全理解的情况下使用该简写*没有类方法*红宝石.(实际上,也没有"单例方法"这样的东西:单例方法只是常规方法,恰好在对象的单例类中定义.)然而,OP显然不是*经验丰富的Rubyist因此,用速记混淆他并不是一个好主意.竖起大拇指! (9认同)

kri*_*ard 47

在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
Run Code Online (Sandbox Code Playgroud)

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

Java中的静态方法有两个不同的特性,使它们与实例方法不同:a)它们是静态的,b)它们不与实例相关联.(IOW:它们真的不像方法,它们只是程序.)在Ruby中,所有方法都是动态的,并且所有方法都与实例相关联.事实上,与Java有三种不同的"方法"(实例方法,静态方法和构造函数)不同,Ruby中只有一种方法:实例方法.所以,不,Java中的静态方法与Ruby中的方法完全不同. - JörgWMittag 1小时前

  • Java中的静态方法有两个不同的特性,使它们与实例方法不同:a)它们是静态的,b)它们不与实例相关联.(IOW:它们实际上不像方法*,它们只是程序.)在Ruby中,*all*方法是动态的,*all*方法与实例相关联.实际上,与Java有三种不同的"方法"(实例方法,静态方法和构造函数)不同,Ruby中只有*一种*方法:实例方法.所以,不,Java中的静态方法与Ruby中的方法完全不同. (2认同)

kos*_*tja 10

声明方法时,self声明的声明是声明类/模块,所以有效地定义了一个类方法.这就像staticjava中的方法.您可以在类而不是实例上调用该方法:MyClass.method

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

编辑:虽然self关键字类似于thisjava中的关键字,但使用self类方法声明的效果类似于static在java 中使用关键字的效果.相似之处在于,使用类对象iself而不是类的实例来访问java中的静态方法,如ruby中的类方法.

请注意,static这并不代表动态的反面.此关键字的名称选择是有问题的(可能是从C继承而来),而应该被调用perClass或类似,以更好地反映其含义.技术含义是static每个类加载器只存在一次所有成员.

  • @JörgWMittag:它至少在某种意义上就像Java的`static` - 它适用于类级别而不是实例级别. (5认同)
  • @JörgWMittag - <什么都没有>对于具有明显相似性的东西来说是一个相当强大的术语(肯定存在差异).添加了一些信息来澄清我的观点. (5认同)
  • 它*根本*不像`static`。特别是,这些方法是动态的,而不是静态的。 (2认同)