Ruby 中的运算符重载
Ruby 允许运算符重载,允许定义运算符在特定程序中的使用方式。例如,“+”运算符可以定义为执行减法而不是加法,反之亦然。可以重载的运算符运算符+、-、/、*、**、%等,不能重载的有&、&&、|、||、()、{}、~等。
运算符功能与普通功能相同。唯一的区别是,运算符函数的名称始终是运算符后跟运算符对象的符号。使用相应的运算符时调用运算符函数。运算符重载不是可交换的,这意味着 3 + a 与 a + 3 不同。当有人尝试运行 3 + a 时,它将失败。
下面是 Ruby 运算符重载的示例。
例子:
# Ruby program of Operator Overloading
class Car
attr_accessor:name, :color
# Initialize the name and color
def initialize(name, color)
@name = name
@color = color
end
def +(obj)
return Car.new("#{self.name}#{obj.name}",
"#{self.color}#{obj.color}")
end
end
a = Car.new("Mercedes", "Red")
b = Car.new("Audi", "Silver")
puts (a+b).inspect
输出 :
#
正如我们所见,'+'运算符已被重载,因此它返回两个连接的字符串输出名称和颜色。
这是另一个使用相同代码的示例,但这次我们重载了 '/' 运算符,而不是 '+'运算符运算符。
例子:
# Ruby program of Operator Overloading
class Car
attr_accessor:name, :color
# Initialize the name and color
def initialize(name, color)
@name = name
@color = color
end
def /(obj)
return Car.new("#{self.name}#{obj.name}",
"#{self.color}#{obj.color}")
end
end
a = Car.new("Mercedes", "Red")
b = Car.new("Audi", "Silver")
puts (a/b).inspect
输出 :
#
我们可以看到输出是相同的,因为在上述情况下,我们重载了 '/'运算符来执行连接,因此我们可以重载任何运算符而不管其通常用法。
在下面的示例中,我们将尝试重载可比较的运算符:
(注意:在此我们将使用 ruby 模块 Comparable。在 Ruby 中,Comparable 模块由其对象可能被排序的类使用。如果接收者小于另一个对象,则返回 -1,如果接收者相等到另一个对象,则返回 0。如果接收者大于另一个对象,则返回 1。)
例子:
# Ruby program of Operator Overloading
class Comparable_operator
include Comparable
attr_accessor:name
# Initialize the name
def initialize(name)
@name=name
end
def <=>(obj)
return self.name<=>obj.name
end
end
a = Comparable_operator.new("Geeks for Geeks")
b = Comparable_operator.new("Operator Overloading")
puts a<=>b
输出 :
false
在上面的例子中,输出是假的,因为 ASCII 码 'G'(ASCII=71) 小于 'O'(ASCII=79),因此在检查 71 是否大于 79 之后,它给出的输出是假的。 (注:我们也可以使用=、==、运算符来检查)
这是另一个使用相同代码的示例,但这次我们将比较实际的字符串:
例子:
# Ruby program of Operator Overloading
class Comparable_operator
include Comparable
attr_accessor:name
# Initialize the name
def initialize(name)
@name=name
end
def <=>(obj)
return self.name<=>obj.name
end
end
puts "Geeks for Geeks"<=>"Operator Overloading"
输出 :
-1
在上面的示例中,输出为 -1,因为 ASCII 代码 'G' 小于 'O'
在下面的示例中,我们将尝试通过整数重载运算符:
例子:
# Ruby program of Operator Overloading
# By an Integer
class Tester
attr_accessor:num
# Initialize the num
def initialize(num)
@num = num
end
# Define + to do addition
def +(obj)
return @num+obj
end
# Define * to do Multiplication
def *(obj)
return @num*obj
end
def **(obj)
return @num**obj
end
end
a=Tester.new(5)
puts a + 3
puts a * 3
puts a ** 3
输出 :
8
15
125
如果我们传递了一个整数对象,我们将使用关键字来识别变量。
例子:
# Ruby program of Operator Overloading
class Tester
attr_accessor:num
# Initialize the num
def initialize(num)
@num = num
end
# Define + to do addition
def +(obj)
return self.num+obj.num
end
# Define * to do Multiplication
def *(obj)
return self.num*obj.num
end
def **(obj)
return self.num**obj.num
end
end
a = Tester.new(5)
b = Tester.new(4)
puts a + b
puts a * b
puts a ** b
输出 :
9
20
625
(Note: Operator Overloading is not a commutative operation, i.e., if we have used 3 + a in instead of a + 3 we would have got an error like this:
source_file.rb:17:in `+’: Tester can’t be coerced into Fixnum (TypeError)
from source_file.rb:17:in `’)
在下面的示例中,我们将尝试重载元素引用运算符:
(注意:'+='运算符必须通过 +运算符定义,即,我们只需要定义 '+'运算符,编译器会自动使用它,就像 '+=' 和 '<<'运算符追加数组末尾的元素)
例子:
# Ruby program of Operator Overloading
class Array_Operators
attr_accessor:arr
# Initialize the array
def initialize(*arr)
@arr = arr
end
def [](x)
@arr[x]
end
def [] = (x, value)
@arr[x] = value
end
def <<(x)
@arr << x
return ('#{@arr}')
end
end
a = Array_Operators.new(0, 3, 9, 27, 81)
puts a[4]
a[5] = 51
puts a[5]
puts a << 41
puts a[6]
输出 :
81
51
[0, 3, 9, 27, 81, 51, 41]
41
我们可以看到我们的运算符已经按定义工作,并且显示了数组的所有元素。因此,我们可以轻松地重载 Ruby 中的大多数运算符以满足我们的需求。