我在理解 Ruby 中变量和符号的语法时遇到了一些麻烦。我正在阅读一本名为 Agile Web Development with Rails 4 的书。我正在尝试同时学习 Ruby 和 Rails,以便我可以构建网站。
我一直在看的书和教程,有时候变量前面有“@”符号,然后有些变量前面没有@符号。它们之间有什么区别?
另外,我对结肠感到困惑。有时我看到冒号在前面的变量,例如:order,然后我看到冒号在末尾的变量,例如冒号:。我不明白结肠在做什么。
请帮助我理解 Ruby 语法。
我在理解 Ruby 中变量和符号的语法时遇到了一些麻烦。我正在阅读一本名为 Agile Web Development with Rails 4 的书。我正在尝试同时学习 Ruby 和 Rails,以便我可以构建网站。
我一直在看的书和教程,有时候变量前面有“@”符号,然后有些变量前面没有@符号。它们之间有什么区别?
另外,我对结肠感到困惑。有时我看到冒号在前面的变量,例如:order,然后我看到冒号在末尾的变量,例如冒号:。我不明白结肠在做什么。
请帮助我理解 Ruby 语法。
以 开头@
的变量是实例变量,在其他语言中是“属性”。而“经典”变量在其方法/块的范围内是本地的,而实例变量对于特定instance
的对象来说是本地的,例如:
class Foo
def initialize(bar)
@bar = bar
end
def bar
@bar # the variable is specific to this instance
end
def buzz
buzz = 'buzz' # this variable is not accessible outside of this method
end
end
您可能还会看到以 开头的变量@@
,它们是类变量,可以被类的每个实例访问并与子类的每个实例共享。通常不鼓励使用这些变量,主要是因为子类共享变量,这会导致很多混乱。
在 Ruby 中,一切都是对象,类是对象(类的实例Class
),因此您还可以拥有类实例变量:
class Foo
def self.bar
@bar #we are in class Foo's scope, which is an instance of class Class
end
def self.bar=(bar)
@bar = bar
end
def bar
@bar # Foo.new.bar != Foo.bar
end
end
您所说的“带冒号的变量”不是变量。它们是一种特殊类型的字符串,称为符号,它是不可变的,并且针对解释器的快速识别进行了优化,事实上,它们作为指针在内部存储,因此这:this == :this
是一个非常快速的操作。
此属性使它们成为哈希键的良好候选者,因为它们提供快速检索或“标志”传递给方法;将它们视为一种松散的常数,“代表”他们所说的话。它们的不变性也很危险:曾经创建的所有符号都不会被垃圾收集;通过创建数千个符号很容易造成内存泄漏,因此请明智地使用它们。
更新,因为 ruby 2.2 符号在某些情况下可能会被垃圾收集(当没有保留参考并且不需要比较时)
带有@
符号的变量是实例变量。这意味着只要声明它们的类的实例持续存在,它们就会持续存在。因此,如果您有一个名为的类Message
并且每条消息都有一个名为 的变量@subject
,那么当您实例化一条新消息时,只要消息对象本身存在,它就会将该主题变量保留在内存中。现在,如果它没有@
符号,一旦它在“超出范围”中声明的函数又名完成,该变量将“丢失”,因为函数完成并且内存被 Ruby VM 回收。还有以两个@
符号开头的“类变量”。这意味着该变量在类的所有实例之间共享。
至于冒号,如果它在变量之前,则意味着它是一个“符号”,它通常用作 Ruby 中哈希和其他数据位的标识符。如果它位于单词的末尾,则意味着它是 Ruby 1.9+ 语法中哈希标识符的关键部分。
有时变量前面有“@”符号,然后有些变量前面没有@符号。
带"@"
符号的变量是实例变量,前面不带@
,可以是常量,也可以是局部变量,也可以是全局变量。阅读Ruby Programming/Syntax/Variables and Constants。
有时我会看到冒号在前面的变量,例如 :order
它们被称为符号。
然后我看到冒号结尾的变量,例如冒号:。我不明白结肠在做什么。
这些可能是哈希语法(正如您给我们的提示,所以我猜),其中键是符号。示例:{foo: 1}
- 这是一个哈希。
另请按照您的要求阅读:
实例变量: ( @foo = '123'
) 定义了一个实例变量,并在整个请求的当前实例中保持其值。在 rails mvc 范例中,最常见的实例变量用于帮助将数据从控制器传递到视图,并允许您在控制器的一部分中定义事物并在另一部分中使用。
class ProjectsController < ApplicationController
before_filter :find_project
def show; end
def update
if @project.update_attributes(params[:project])
...
end
end
private
def find_project
@project = Project.find(params[:id])
end
end
在上面的代码中,您可以看到有一个 before 过滤器在每个方法之前运行。在上述情况下,我们找到当前项目并将其保存到实例变量中。并且因为它是一个实例方法,所以它可以在这个类中的任何地方访问,也可以访问用于呈现 html 的视图。
局部变量: ( foo = '123'
) 顾名思义,它们只能在def
定义它们的当前方法 ( ) 中访问。