简体   繁体   English

括号运算符对Ruby中的FixNum做了什么?

[英]What does the bracket operator do to a FixNum in Ruby?

Coming from Python I find the following behaviour very surprising: 来自Python我发现以下行为非常令人惊讶:

irb(main):211:0> x= 33
=> 33
irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0

Is there a rationale/philosophy for not raising an error in this example? 在这个例子中是否存在不提出错误的理由/理念?

The bracket operator gives you the nth bit of the binary representation: 括号运算符为您提供二进制表示的第n位:

http://ruby-doc.org/core-2.1.2/Fixnum.html#method-i-5B-5D http://ruby-doc.org/core-2.1.2/Fixnum.html#method-i-5B-5D

You might be a little confused about what this is doing internally, but that's normal when dealing with Ruby because it's quite unlike other scripting languages. 你可能对内部的工作有点困惑,但在处理Ruby时这是正常的,因为它与其他脚本语言完全不同。 Unless you've used SmallTalk it might even seem insane. 除非你使用过SmallTalk ,否则它可能看起来很疯狂。

When Ruby sees the following code: 当Ruby看到以下代码时:

x = 6
x[1]

What it's actually doing is this: 它实际上做的是这样的:

x.send(:[], 6) # Send :[] method call to x with arguments [ 6 ]

The x object is free to interpret that however it wants, and the behaviour is typically (though not always) defined by the class x belongs to if x is a normal instance. x对象可以自由地解释它想要的,并且行为通常(但不总是)由类x定义,如果x是普通实例则属于x

In this case it's returning the bit at a given index, equivalent to x & (1 << 6) >> 6 . 在这种情况下,它返回给定索引处的位,相当于x & (1 << 6) >> 6

Sometimes the [] method does several things: 有时候[]方法做了几件事:

string = "brackets"

# Retrieve a single character
string[1]
# => "r"

# Retrieve a substring
string[5,2]
# => "et"

# Perform a pattern match
string[/[^aeiou]+/]
# => "br"

This also does some pretty crazy things since you can apply it to a Proc as well: 这也做了一些非常疯狂的事情,因为你也可以将它应用到Proc:

fn = lambda { |x| x + 1 }

# Conventional (explicit) call
fn.call(2)
# => 3

# Square bracket method
fn[5]
# => 6

Since Ruby leans very heavily on Duck Typing , this means that you can write a Proc to fill in where you'd normally have a Hash or an Array and the method receiving your object is none the wiser. 由于Ruby非常依赖Duck Typing ,这意味着您可以编写一个Proc来填充您通常拥有Hash或Array的位置,并且接收您的对象的方法并不明智。

It's this flexibility in leaving the meaning of x[...] for your own class instance x up to you that makes it pretty powerful. 正是这种灵活性将x[...]含义留给了你自己的类实例x ,这使得它非常强大。

For example: 例如:

class Bracketeer
  def [](i)
    "%d brackets" % i
  end
end

bracketeer = Bracketeer.new

bracketeer[6]
# => "6 brackets"

This simple notation often comes in handy when you're trying to create a minimal interface for a class of yours. 当您尝试为您的类创建最小接口时,这种简单的表示法通常会派上用场。 In many cases you can use something simple like [] to replace what would be a more verbose method like find_by_id or cache_fetch . 在许多情况下,您可以使用像[]这样简单的东西来替换像find_by_idcache_fetch这样更冗长的方法。

Certainly. 当然。 You'll find that the manual is quite illuminating. 你会发现手册非常有启发性。

This is returning the binary bit for the bit position value as a zero or one. 这将比特位置值的二进制位返回为零或一。

It is returning the n'th bit as rightfully observed by @msergeant. 它正在返回@msergeant正确观察到的第n位。

What this means is, for the number 33, its binary representation is: 这意味着,对于数字33,其二进制表示是:

Index : [7][6][5][4] [3][2][1][0]
Bits  :  0  0  1  0   0  0  0  1

Which explains the output: 这解释了输出:

irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM