`

娃娃鸭学Ruby-23、赋值

阅读更多
赋值
一个赋值表达式可以为一个或多个左值(lvalue)指定一个或多个值。
左值  可以出现在一个赋值操作符左侧的东西。

在Ruby中变量、常量、属性及数组元素是左值。

在Ruby中三种不同形式的赋值表达式。
x=1
x,y,z=1,2,3   # set x to 1,y to 2 ,z to 3
x=y=0  #从右到左的顺序依次求值

幂等
赋值操作不是幂等的。

1、对变量进行赋值
Ruby拥有四种类型的变量:局部变量、全局变量、实例变量及类变量
赋值操作的行为是一样的

Ruby的实例变量是永远不可见的。
point.x,point.y=1,2
左值不是变量而是属性。

class Ambiguous
  def x;1;end # 方法x,返回值1
  def test
     puts x
     x=0 if false
     puts x  # x 是一变量,没有被赋值,打印nil
     x=2    #赋值
     puts x  #打印2
  end
end

2、对常量赋值
常量变量区别
      常量在程序执行期间,值保持不变
针对常量赋值的特殊规则:
   1)已存在的常量进行赋值会导致Ruby发出一个警告,然后Ruby仍然会执行这个赋值,意味着常量并不是真正恒久不变的
   2)方法体内部是不允许对常量进行赋值的

3、对属性和数组元素的赋值
Ruby中对属性或数组元素的赋值其实是对方法调用的简写。
对象具有名为m=的方法,方法名的最后一个字符是等号,那么o.m可以作为赋值表达式的右值。
更进一步
o.m=v
Ruby解释器将转换成:
o.m=(v)

[]=
o[x]=y   # o.[]=(x,y)
o[x,y]=z # o.[]=(x,y,z)

4、缩写形式的赋值
x+=1
+=并不是真正的Ruby操作符,只是缩写
x=x+1

缩写仅在只有一个左值和一个右值的情况下才有效的。
   当左值是一个属性时,可以采用缩写形式
      o.m+=1
      o.m=(o.m()+1)
   当左传旧一个数组元素时,可采用缩写
       o[x]-=2
       o.[] =(x,o.[](x)-2)
常见的缩写:
  赋值操作                     展开形式
x+=y                          x=x+y
x-=y                           x=x-y
x*=y                          x=x*y
x/=y                          x=x/y
x%=y                        x=x%y
x**=y                       x=x**y
x&&=y                       x=x&&y
x||=y                    x=x||y
x&=y                        x=x&y
x|=y                        x=x|y
x^=y                       x=x^y
x<<=y                    x=x<<y
x>>=y                    x=x>>y

result ||= []
result= result ||[]

5、并行赋值
多个左值之间采用逗号进行分隔,多个右值之间也是如此。
几种情况:
  1)左值和右值的数量相等
     x, y, z =1, 2, 3  # x=1;y=2;z=3
x,y=y,x #交换两变量
x=y;y=x # 两值相同
  2)一个左值,多个右值
  Ruby会创建一个数组来容纳所有右值,并赋给左值
  x=1,2,3  # x=[1,2,3]
可以在左值前放一个*,不会改变这个赋值操作的意义,也不会改变返回值。
不希望出现多个右值被放到一个数组,在左值后接一个逗号
x,=1,2,3 # x=1;其他值无效
  3)多个左值,一个数组右值
当有多个左值,但是只有一个右值时。
Ruby试图将右值扩展成一个值列表,然后再进行赋值。
x,y,z=[1,2,3] # x,y,z=1,2,3
x=[1,2]  #x变在[1,2]
x,=[1,2] #x=1,
4)左值和右值的数量不同
左值多,多的用nil
右值多,多的丢弃
x,y,z=1,2 # x=1;y=2;z=nil
x,y=1,2,3 # x=1;y=2;3丢弃
  5)展开操作符
如果一个右值以*开头,就意味着它是一个数组(或一个类似于数组的对象)
x,y,z=1,*[2,3] # same as x,y,z=1,2,3
在Ruby1.8中*只能出现在最后一个右值的前面
在Ruby1.9中一个并行赋值的右值列表里可以出现任意多个*,而且它们可以出现在列表的任何位置。

**都是非法的
x,y=**[[1,2]]  #syntaxError!

当一个左值前放*时,意味着所有多外出来的右值都被放入一个数组并赋给该左值。
x,*y=1,2,3 # x=1;y=[2,3]
x,*y=1,2   # x=1;y=[2]
x,*y=1      #x=1;y=[]

在Ruby1.8里,*只能出现在最后一个左值的前面
Ruby1.9里,并行赋值的左侧只能出现一个*,但是它右以出现在左侧任何位置。
*x,y=1,2,3   #x=[1,2] ; y=3
*x,y=1,2     #x=[1];y=2
*x,y=1        #x=[];y=1

两侧都出现*
x,y,*z=1,*[2,3,4]  # x=1,y=2,z=[3,4]

   6)并行赋值中的圆括号
子赋值
x,(y,z)=a,b
同时进行两个赋值操作
x=a
y,z=b

x,y,z=1,[2,3] # x=1,y=[2,3];z=nil
x,(y,z)=1,[2,3] #x=1,y=2,z=3

a,b,c,d=[1,[2,[3,4]]]  # no parens : a=1;b=[2,[3,4]];c=d=nil
a,(b,(c,d))=[1,[2,[3,4]]] # parens:a=1,b=2,c=3,d=4
  
    7)并行赋值的值
并行赋值表达式的返回值是所有右值构成的数组。
如果一个并行赋值紧跟在一个方法名之后,Ruby不会将并行赋值中的逗号解释成左值和右值之间的分隔符,而是解释成该方法的参数分隔符。
  puts x,y=1,2
Ruby认为:puts三个参数:x,y=1以及2

puts (x,y=1,2)   #还是不行,因为在Ruby中括号可以省略
如果想并行赋值:
puts((x,y-1,2)) #这样才行。

2011-4-10 16:19 danny
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics