【问题标题】:What does def `self.function` name mean?def `self.function` 名称是什么意思?
【发布时间】:2012-12-04 15:34:15
【问题描述】:

谁能向我解释在方法定义中添加self 是什么意思?是不是类似于java中的this关键字?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    与其他语言相反,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 爱好者有时会使用术语“类方法”来表示“类对象的单例类的实例方法”,但他们只是在充分理解 没有类方法这样的东西的情况下使用这种简写形式 在 Ruby 中。 (事实上​​,也没有所谓的“单例方法”:单例方法只是恰好在对象的单例类中定义的常规方法。)然而,OP显然是不是 i> 一位经验丰富的 Rubyist,因此将他与速记混淆并不是一个好主意。竖起大拇指!
    • 当引用一个模块而不是一个类时,这个含义会改变吗?
    • @Adrian - 在功能上它的工作原理是一样的。例如,如果您在模块Foo 中有def self.bar,那么您可以调用Foo.bar。但是,不同之处在于模块在技术上是Module 类的实例,它是Class 类的实例(即所有类的类)。这与上面 Bernards 回答中的 A 不同,它是“一个类”,它只是 Class 的一个实例。希望这会有所帮助!
    【解决方案2】:

    在 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。特别是,这些方法是动态的,而不是静态的。
    • 如果你在 ruby​​ 中用 def self.method ... 定义 Class#method,它有点像 java 中的 class JavaClass; public static void method ...
    • Java 中的静态方法有两个不同的特点,使它们不同于实例方法:a) 它们是静态的,b) 它们与实例无关。 (IOW:它们真的不像方法根本,它们只是过程。)在 Ruby 中,all 方法是动态的,而 all方法与实例相关联。事实上,与 Java 中存在三种不同的“方法”(实例方法、静态方法和构造函数)不同,Ruby 中只有 一种 方法:实例方法。所以,不:Java 中的静态方法与 Ruby 中的方法完全不同。
    【解决方案3】:

    当声明一个方法时,声明的self 是声明的类/模块,所以实际上你定义了一个类方法。对于客户端,这类似于 java 中的 static 方法。客户端将调用类而不是实例上的方法:MyClass.method

    Here你可以找到更多关于类和实例方法的细节。

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

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

    【讨论】:

    • 什么都没有static。特别是,这些方法是动态的,而不是静态的。
    • @JörgWMittag:至少在某种意义上,它就像 Java 的 static——它适用于类级别而不是实例级别。
    • @JörgWMittag - 是一个相当强的术语,用于表示具有明显相似性的事物(当然也存在差异)。添加了一些信息来澄清我的观点。
    • @kostja 我认为在这种情况下,Java 中的static 指的是静态绑定(即在编译时确定要调用的方法),而不是用于实例方法的动态绑定。所以从这个意义上说,它确实代表了动态的对立面,但是关键字 static 确实具有不切实际的重载含义,尤其是。在 C 中。
    • 是的,我的第一个错误是说“就像 Java 中的静态”。我只关心方法绑定。然后讨论失控了:)现在改变了最初的措辞。
    猜你喜欢
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多