论坛首页 编程语言技术论坛

Ruby 运算符小结

浏览 5439 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-07   最后修改:2009-02-07

个人感觉《Ruby程序设计语言》确实是一本好书,它将Ruby的枝枝节节都点到了。

在这里,我从自己的一些心得出发,对Ruby语言的操作符做个读书笔记式的小结。

 

欢迎补充......

 

运算符一览表(注意从上到下优先级依次降低 ):

 

运算符 作用的运算数数目 (左/右)结合律 是否可以重新定义 具体操作含义 备注
!   ~   + 1 可以 逻辑取否,位运算取反,算术取正(正号)

在Ruby1.9中重新定义正号时使用 +@. ~x=-x-1.

!在Ruby1.9中可以重新定义,1.8中不行.

** 2 可以 这个运算和我们数学上的幂运算是一致的。 符合右结合律: x**y**z == x**(y**z)
- 1 可以 算术取负(负号) 在Ruby1.9中重新定义正号时使用 -@.优先级和“正号”不同
*   /   % 2 可以 算术乘法/字符串重复/数组操作、除法(根据类型的不同可能会表现出取整的效果)、取余数

整数除法:取整

整数/0 raise ZeroDivisionError

正浮点数/0 =  Infinity

负浮点数/0 =  -Infinity

0.0/0 = NaN

 

irb(main):001:0> a=[0]
=> [0]
irb(main):002:0> a*=2
=> [0, 0]
irb(main):003:0> a*=3
=> [0, 0, 0, 0, 0, 0]

 

irb(main):004:0> a='.'
=> "."
irb(main):005:0> a*=2
=> ".."
irb(main):006:0> a*=3
=> "......"

 

+   - 2 可以 算术加法/字符串连接/数组合并、算术减法/数组差 irb(main):001:0> a=[1,2,3]
=> [1, 2, 3]
irb(main):002:0> b=[4]
=> [4]
irb(main):003:0> c=a+b
=> [1, 2, 3, 4]
irb(main):004:0> c-=b
=> [1, 2, 3]
<<   >> 2

可以
 位运算左移/字符串添加/数组添加,位运算右移  irb(main):001:0> a='first'
=> "first"
irb(main):002:0> a<<'second'
=> "firstsecond"
irb(main):003:0> a
=> "firstsecond"
irb(main):004:0> a=[]
=> []
irb(main):005:0> a<<'one'
=> ["one"]
irb(main):006:0> a<<'two'
=> ["one", "two"]
irb(main):007:0> a
=> ["one", "two"]
&
2

可以
位运算和AND/数组交Intersection
irb(main):001:0> (0b1010 & 0b1100).to_s(2)
=> "1000"
TrueClass,FalseClass,NilClass同样定义了&,|,^.用于Boolean运算 ,但是这并不是一个正确的方法.&&,||用于逻辑运算时存在短路 现象,而位操作符没有.
|   ^ 2 可以 位运算或OR/数组并Union,异或XOR irb(main):001:0> (0b1010 & 0b1100).to_s(2)
=> "1000"
irb(main):002:0> (0b1010 | 0b1100).to_s(2)
=> "1110"
irb(main):003:0> (0b1010 ^ 0b1100).to_s(2)
=> "110"
irb(main):001:0> a=[1,2,3]
=> [1, 2, 3]
irb(main):002:0> b=[2,3,4]
=> [2, 3, 4]
irb(main):003:0> a+ b
=> [1, 2, 3, 2, 3, 4]
irb(main):004:0> a| b
=> [1, 2, 3, 4]
irb(main):005:0> a- b
=> [1]
irb(main):006:0> a& b
=> [2, 3]
<   <=   >=   > 2 可以 大小顺序判断:小于/继承(类间关系),小于等于,大于等于,大于/泛化(类间关系) data大小顺序关系:数值、字符串、日期。类层次关系,父子关系,非父子关系
irb(main):001:0> String < Object
=> true
irb(main):002:0> Object>Numeric
=> true
irb(main):003:0> Numeric<Integer
=> false
irb(main):004:0> String<Numeric
=> nil
==   ===   !=   =~   !~   <=> 2

直接结合,无所谓左右结合律。如果在一个表达式中出现了多个此类符号必需使用小括号'(',')'隔开。

irb(main):001:0> true==false==false
SyntaxError: compile error
(irb):1: syntax error , unexpected tEQ
......
irb(main):002:0> true==false<=>false
SyntaxError: compile error
(irb):2: syntax error , unexpected tCMP
......

可以

==以左操作数为基准测试相等,!=返回==的取反值,===主要用于case-when语句中的匹配操作,=~用于模式匹配操作判断,!~是=~取反。

 

<=>是一个通用的大小判断操作,很多时候比较操作都是在本操作基础上做一些修饰。  

a<=>b :值  返回值

  • a<b  -1
  • a==b 0
  • a>b  1
  • 不能比较  nil

关于对象的相同操作:

  • equal?   主要用于判断标识符指向的对象是否为同一个。对于任意两个不同的实体对象,本方法一定返回false。在底层实现应该就是直接查看内存地址是否相同。在通常状况下,子类不能重写本方法。另外可以通过考察独享的object_id来判断是否是两个对象。
  • ==   这是一个最常用的考察相同的操作,在普通的object中,其行为和equal?相同。不过很多class重定义本操作来实现其它有意义的判断(字符串、数值型)。对于两个数组使用==,是先判断长度相同,然后判断每个对应位置上的==状况。而哈希表使用==,是先判断长度,然后判断key/value键值对的相同情况(key采用eql?方法判断,而value采用==判断 )。
  • eql?   很多时候本方法被重写为直接调用==。
  • ===   主要用于case-when语句中的匹配判断。Range类型中用于判断是否包含,而在Regexp中则用于是否匹配表达式。irb(main):001:0> (1..10)===5
    => true  #范围
    irb(main):002:0> /\d+/==="123"
    => true  #正则表达式
    irb(main):003:0> String === "s"
    => true  #具体对象和
    irb(main):004:0> :s==="s"
    => false  #标号类型,Ruby1.8中为false,而1.9中则为ture
  • =~   主要用于String和Regexp类型中的模式匹配操作。!~ 为 =~取反
&& 2 不能 逻辑与

在Ruby的Boolean表达式中,expression表现出逻辑非时只有两种情况(false, nil),其它任何状况下均为true.

特殊的表示:

irb(main):001:0> x=true
=> true
irb(main):002:0> x && p(x.to_s)
"true"
=> nil
irb(main):003:0> x=nil
=> nil
irb(main):004:0> x && p(x.to_s)
=> nil
#在这里相当于 p(x.to_s) if x

|| 2 不能 逻辑或 优先级低于 &&
..   ... 2

只能 是两个数据。

irb(main):001:0> 1..2...3
SyntaxError: compile error
(irb):1: syntax error, unexpected tDOT3
......
irb(main):002:0> (1..2)...3
ArgumentError: bad value for range
    from (irb):2

不能 区间/flip-flop开闭表达式

区间包含字面量区间(1..3, 1...4)和变量区间(x..x*x, x+1...x+x*x).

关于开闭表达式有记忆 属性:

irb(main):001:0> (1..10).each{|x| p x if x==3.. x>=3}
3
=> 1..10
irb(main):002:0> (1..10).each{|x| p x if x==3... x>=3}
3
4

=> 1..10

 

$stateTwoPoint = false
#exp1..exp2
def flipflopTwoPoint(exp1,exp2)
  if !$stateTwoPoint
    result = exp1
    if result
      $stateTwoPoint = ! exp2
    end
    result
  else
    $stateTwoPoint = ! exp2
    true
  end
end

$stateThreePoint = false
#exp1...exp2
def flipflopThreePoint(exp1,exp2)
  if !$stateThreePoint
    $stateThreePoint = exp1
  else
    $stateThreePoint = ! exp2
    true
  end
end

 以上的exp1,exp2都是逻辑表达式,每次运行时都要重新计算。

?: 3 不能 三目条件表达式

expression ? valueLeft : valueRight

if expression then

   valueLeft

else

   valueRight

end

 

满足右结合律:

a ? b:c?d:e等同于 a?b : (c?d:e)

rescue 2 不能 错误恢复
Rescue 语句修饰句 写道
一个语句可以有个可选的rescue修饰句跟在另一个语句后面(来扩展另一个rescue修饰句,等等)。Rescue修饰句不接受异常参数,它挽救StandardError和它的子类。
如果一个异常在rescue修饰句的左侧被引发,左侧的语句被放弃,全部行值是右边语句的值。
 
=   **=   *=    /=   %=   +=    -=   <<=   >>=   &&=   &=    ||=     |=      ^= 2 不能 赋值语句 赋值语句
defined? 1 可以看成一个method 方法/行为 不能 测试变量和类型等是否定义 如果没有定义则返回nil,已经定义则返回字符串(情况比较复杂,在这里不做讨论)
not 1 不能 逻辑非 比!优先级低
and   or 2 不能 逻辑与、逻辑或

比&&,||优先级低。即

defined? a and defined? b #等同于 (defined? a) and (defined? b)

defined? a && defined? b #等同于 defined? ((a && (defined? b)))

if    unless   while   until 2

特殊 修饰词

大体格式是

待执行语句  XXX(关键字)   条件

不能 条件/循环修饰语句

statement if expression #expression为真则执行statement

statement if expression #expression为假则执行statement

statement while expression #expression为真则循环statement

statement while expression #expression为假则循环statement

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics