什么<<在Ruby中意味着什么?

Vya*_*nov 61 ruby arrays operators

我有代码:

  def make_all_thumbs(source)
    sizes = ['1000','1100','1200','800','600']
    threads = []
    sizes.each do |s|
      threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
    end
  end
Run Code Online (Sandbox Code Playgroud)

什么<<意思?

emb*_*oss 112

'<<'作为普通方法

在大多数情况下,'<<'是一个像其他方法一样定义的方法,在你的情况下它意味着"添加到这个数组的末尾"(另见这里).

这是在你的特殊情况下,但也有很多其他场合你会遇到"<<"方法.我不会将其称为'运算符',因为它实际上是一个在某个对象上定义的方法,可以被您覆盖或为您自己的对象实现."<<"的其他案例

  • 字符串连接:"a"<<"b"
  • 将输出写入IO:io <<"一行文本\n"
  • 将数据写入消息摘要,HMAC或密码:sha <<"要散列的文本"
  • 左移一个OpenSSL :: BN:bn << 2
  • ...

单例类定义

然后是程序流程中当前范围(=自我更改)的神秘转变:

class A
  class << self
    puts self # self is the singleton class of A
  end
end

a = A.new
class << a
  puts self # now it's the singleton class of object a
end
Run Code Online (Sandbox Code Playgroud)

这个谜团class << self让我惊讶并调查那里的内部.在我提到的所有例子中<<,实际上是一个在类中定义的方法,即

obj << stuff
Run Code Online (Sandbox Code Playgroud)

相当于

obj.<<(stuff)
Run Code Online (Sandbox Code Playgroud)

class << self构建体(代替自或任何对象)是真正的不同.它实际上是语言本身的内置功能,在CRuby中它被定义为parse.y as

k_class tLSHFT expr
Run Code Online (Sandbox Code Playgroud)

其中tLSHFT是'<<'标记,k_class是'class'关键字,expr是任意表达式.也就是说,你实际上可以写

class << <any expression>
Run Code Online (Sandbox Code Playgroud)

并将"转移"到表达式结果的单例类中.tLSHFT序列将被解析为'NODE_SCLASS'表达式,称为Singleton类定义(参见node.c)

case NODE_SCLASS:
    ANN("singleton class definition");
    ANN("format: class << [nd_recv]; [nd_body]; end");
    ANN("example: class << obj; ..; end");
    F_NODE(nd_recv, "receiver");
    LAST_NODE;
    F_NODE(nd_body, "singleton class definition");
    break; 
Run Code Online (Sandbox Code Playgroud)

这里的文件

而且,我怎么能忘记那些,这里的文档使用'<<'的方式又是完全不同的.您可以通过声明方便地定义跨越多行的字符串

here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_
Run Code Online (Sandbox Code Playgroud)

要区分'here doc operator',任意String定界符必须紧跟'<<'.初始分隔符和第二次出现的相同分隔符之间的所有内容都将成为最终字符串的一部分.也可以使用'<< - ',不同之处在于使用后者将忽略任何前导或尾随空格.

  • 非常彻底的答案。可能会使初学者感到困惑,但正如一个明智的人(可能)说的那样,“问一个广泛的问题,得到一个彻底的答案”。 (2认同)

sha*_*jin 27

主要用于数组中,将值附加到数组的末尾.

a = ["orange"]
a << "apple"
puts a
Run Code Online (Sandbox Code Playgroud)

给出这个

  ["orange", "apple"] 
结果.

  • 在[类继承]中再次使用`<<`(http://stackoverflow.com/questions/6182628/ruby-class-inheritance-what-is-double-less-than) (3认同)

Emi*_*ggi 7

它是允许您通过追加新项目来提供现有数组的运算符.

在上面的示例中,您只需threads使用5个新线程填充空数组.


Adi*_*rji 6

'a << b'表示将b附加到a的末尾


shu*_*hra 6

在 ruby​​ 中,'<<' 运算符主要用于:

  1. 在数组中附加一个值(在最后一个位置)

    [2, 4, 6] << 8 它会给出 [2, 4, 6, 8]

  2. 它还用于 ruby​​ 中的一些活动记录操作。例如,我们有一个 Cart 和 LineItem 模型关联为cart has_many line_items。Cart.find(A).line_items 将返回 ActiveRecord::Associations 对象,其中包含属于购物车“A”的行项目。

现在,要添加(或说关联)另一个 line_item (X) 到购物车 (A),

Cart.find(A).line_items << LineItem.find(X)
Run Code Online (Sandbox Code Playgroud)
  1. 现在将另一个 LineItem 添加到同一个购物车“A”,但这次我们不会创建任何 line_item 对象(我的意思是不会手动创建 activerecord 对象)

    Cart.find(A).line_items << LineItem.new

在上面的代码中,<< 将保存对象并将其附加到左侧活动记录关联数组。

以及上面答案中已经涵盖的许多其他内容。


小智 5

在红宝石中,您总是有更多的做事方式。因此,Ruby为常用方法名称提供了一些不错的快捷方式。像这样用于.push而不是键入.push方法名称,您只需使用<<,即串联运算符。实际上,在某些情况下,您可以对.push和+与<<进行相同的操作。

就像您在此示例中看到的那样:

alphabet = ["a", "b", "c"]
alphabet << "d" # Update me!
alphabet.push("e") # Update me!
print alphabet 
caption = "the boy is surrounded by "
caption << "weezards!" # Me, too!
caption += " and more. " # Me, too!
# .push can no be uses for concatenate 
print caption
Run Code Online (Sandbox Code Playgroud)

所以您看到的结果是:

["a", "b", "c", "d", "e"]
the boy is surrounded by weezards! and more.
Run Code Online (Sandbox Code Playgroud)

您可以使用运算符<<将元素推入数组或将字符串连接到另一个。

因此,这是在创建一个新的元素/对象线程类型并将其推入数组。

 threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
Run Code Online (Sandbox Code Playgroud)