Ruby 的变量

本章节我们将讲解 Ruby 中如何创建一个变量,变量都有哪几种,在什么场景下会使用这些变量。

1. 什么是变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。——官方定义

在 Ruby 中变量用来保存程序要使用的任何数据。

让我们创建一个变量。

2. Ruby中如何创建一个变量

在Ruby中我们使用"变量名称 = 名称的值"这种形式来为变量进行赋值操作。

下面是一些创建不同类型变量的例子:

实例:

name = "小明"
@cars = ['Toyota', 'BMW''Benz']
@@color = 'red'
$global_variable = 10

我们可以通过class方法查看这个变量是什么类型的变量(换种说法,查看这个变量所属的类是什么)。

实例:

> count = 10
=> 10
> count.class
=> Integer

解释:不同于 Java 和 C 等所谓的强变量和静态变量类型,在声明变量的时候必须定义变量类型,此类型的编程语言在定义变量之后不能更改变量的类型。

这个是 C 语言的例子:

int count = 10; 

Ruby 是一种动态的语言,创建变量无需定义变量类型,取而代之的是 Ruby 的解释器查看分配给变量值的类型,并动态计算出变量的类型。这样做的优点是,声明了变量之后,我们可以在之后的代码中动态更改变量而无需去关心它的类型

下面我们来了解在 Ruby 中都有哪几种变量:

3. Ruby中有哪几种变量

在 Ruby 中,根据变量的作用范围(作用域),变量被分为局部变量local variables)、实例变量instance variables)、类变量class variables)、全局变量global variables)4种。另外,Ruby还有一种常量类型(constant)。每种变量都通过在变量名的开头使用特殊字符来声明,如下表所示。

名称开头 作用范围
$ 构造函数,创建新对象时
@ 析构函数,对象的销毁时
[a-z] or _ 局部变量(作用域在定义的一个方法里)
[A-Z] 方法重载,静态调用一个不可访问方法时
@@ 类变量(作用域为一个类)

Ruby 有两个不能分配值的伪变量,一个是 nil,它被分配给未初始化的对象;另一个是 self,它被用来指向正在操作的对象。

3.1 全局变量

Ruby 中的全局变量可以在 Ruby 程序中的任何位置访问,无论它们在何处声明。全局变量名称以美元符号($)为前缀。

实例:

$welcome = "Welcome to Ruby Essentials"

注意事项:不要轻易使用全局变量,问题在于,它们不仅在程序代码中的任何位置都可见,而且还可以在应用程序中的任何位置进行更改。这会使异常追踪变得困难。

3.2 类变量

类变量是在类的所有实例之间共享的变量。这意味着从该类实例化的所有对象仅存在一个变量值。这意味着,如果一个对象实例更改了类变量的值,那么对于所有其他对象实例,该新值将实质上发生更改。类变量通过在变量名前添加两个 @ 字符(@@)来声明,并且类变量必须在创建时初始化。

实例:

@@total = 0

3.3 实例变量

实例变量与类变量相似,不同之处在于它们的值在对象的特定实例中是局部的。例如,如果一个类包含一个称为@total的实例变量,则如果该对象的一个实例更改了@total的当前值,则该更改仅对进行更改的对象是有效的,对于其他的对象是无效的。

这是一个创建包含实例变量的对象的例子(Ruby的类章节中会详细讲解类的创建):

# 这个是Song类,里面有一个setter方法,可以给@title实例变量赋值。
class Song
  def title= name
    @title = name
  end
end

# 创建song1,和song2两个对象
song1 = Song.new
song2 = Song.new

# song1的title为 Welcome my Ruby world
song1.title = "Welcome my Ruby world"
song2.title = "World is perfect"

# 打印两个对象
p song1
p song2

# ---- 输出结果 ----
#<Song:0x007faa5e894648 @title="Welcome my Ruby world">
#<Song:0x007faa5e894620 @title="World is perfect">

解释:从打印结果我们可以看到,我们实例化 song1 和 song2 后传入的title不同,他们的@title发生了改变,但是彼此之间不会互相影响。

在 Ruby 中,实例变量是通过在变量名称前添加一个@符号来声明的。

实例:

@total = 10

Tips:实例变量默认值为 nil。

3.4 局部变量

它们的名称始终以小写字母(a-z)或下划线(_)开头

实例:

loopcounter = 10
_LoopCounter = 20

注意事项

在Ruby中我们调用方法(详情请查看:Ruby的方法)可以省略括号(),这就会导致变量名和方法名可能重名的问题。

实例:

some_thing = 'I am a variable' # 现在我是一个变量

# 定义了一个some_thing的方法
def some_thing
  puts 'I am a method'
end

puts some_thing

# ---- 输出结果 ----
I am a variable

解释:当变量名和方法名称一致的时候,优先使用变量名。

如果我们也要调用方法的话,要在变量名后面增加一个括号()

实例:

puts some_thing()

# ---- 输出结果 ----
I am a method

当局部变量没有定义时被调用会抛出异常。

puts undefined_variable

# ---- 输出结果 ----
ruby.rb:1:in `<main>': undefined local variable or method `undefined_variable' for main:Object (NameError)

局部变量在声明它们的代码结构中是局部的,例如,在方法或循环内声明的局部变量无法在该循环或方法外访问。(在作用域章节中会详细介绍)

loopcounter = 10
def a_method
  puts loopcounter
end
a_method

# ---- 输出结果 ----
ruby.rb:3:in `a_method': undefined local variable or method `loopcounter' for main:Object (NameError) from ruby.rb:5:in `<main>'

解释:因为在a_method方法的作用域中没有找到loopcounter这个局部变量,所以抛出了异常。

3.5 常量

Ruby 常量是一旦分配了值就不应更改的值。我之所以这样说是因为 Ruby 与大多数编程语言的不同之处在于,它允许在声明常量后更改常量值,Ruby 解释器会在更改值后给出警告。常量的每个字母都应该大写,多个单词使用下划线(_)分隔。

它可以在类或模块内声明的常量可在该类或模块的上下文中的任何位置使用。在类或模块外部声明的常量将分配给全局范围。

实例:

TOTAL_COUNT = 10

4. 小结

本章节中我们了解了在 Ruby 中一共有 4 种变量:局部变量、实例变量、类变量、全局变量,他们的作用范围分别方法、对象、类、全局。除此之外在 Ruby 中,常量是一种不应更改的值,通常在类或模块使用。