【问题标题】:What is the name of a [foo, bar] = ["foo", "bar"] feature?[foo, bar] = ["foo", "bar"] 特征的名称是什么?
【发布时间】:2010-10-17 03:49:51
【问题描述】:

我需要知道一些语言提供的这个很酷的功能的正确名称。

仅供参考:在某些语言中,可以通过将值结构分配给“变量”结构来进行多重分配。在问题标题的示例中,它将“foo”分配给 foo,将“bar”分配给 bar。

【问题讨论】:

  • 很酷的功能?真的吗?以前从未听说过,但我发现它只是令人困惑。很快我们将需要一些工具来使代码“程序员可读”。
  • @Damien:哇,反应过度了。
  • @Damien: blub 很多吗?
  • 好吧,对不起,我肯定反应过度了。但最后我很高兴我做到了,因为我从你那里得到了一个非常有趣的读物,马克。谢谢。我保证下次我会摘下我的 Java 眼镜。那些从未犯错的人可以扔第一块石头;o)

标签: language-features


【解决方案1】:

在函数式语言(没有赋值)中通常称为解构绑定,在命令式语言中通常称为解构赋值

某些语言提供该功能的子集,然后将其称为不同的名称。例如,在 Python 中,它与元组、列表或序列一起使用,在 Ruby 中称为 Tuple unpackingList unpackingSequence unpacking。与数组(或可转换为数组的对象)一起使用,称为并行赋值

解构绑定可以变得任意复杂。例如。这个(假想的)绑定

[Integer(a), b, 2, c] = some_array

会将some_array 的第一个元素分配给a,将第二个元素分配给b,将第四个元素分配给c,但如果第一个元素是@987654326 @,第三个元素等于2,长度为4。所以,这甚至包含了一些条件逻辑。

解构绑定是更一般的模式匹配的子集,它是 Haskell、ML、OCaml、F#、Erlang 和 Scala 等函数式语言的标准特性。不同之处在于解构绑定仅允许您拆分结构并将其组件绑定到变量,而模式匹配还匹配这些结构内的值并允许您做出决策,特别是允许您在绑定的上下文中运行任意代码。 (您可以将上述假想的绑定​​视为解构绑定和模式匹配之间的中途。)

以下是使用模式匹配编写的虚构语言中 reverse 函数的经典示例:

def reverse(l: List): List {
  match l {
    when []              { return [] }
    when [first :: rest] { return (reverse(rest) :: first) }
  }
}

【讨论】:

  • @Matthew Flaschen:谢谢。我添加了 Sequence Unpacking 并从描述中删除了“仅”一词。
  • 我的回答(更新)和评论应该更清楚。元组和列表是 Python 中特殊的序列,所以元组解包和列表解包只是序列解包的特例。
【解决方案2】:

在 Python 中称为列表或序列解包:http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences

my_list = ["foo", "bar"]
foo, bar = my_list

【讨论】:

    【解决方案3】:

    在 Ruby 和其他语言中称为并行赋值。

    【讨论】:

      【解决方案4】:

      Perl 和 PHP 称之为列表赋值

      Perl:

      my ($foo, $bar, $baz) = (1, 2, 3);
      

      PHP:

      list($foo, $bar, $baz) = array(1, 2, 3);
      

      【讨论】:

        【解决方案5】:

        如果您将右侧视为元组,则可以将分配视为一种Tuple Unpacking

        【讨论】:

          【解决方案6】:

          在 Erlang 中......嗯,它不是赋值,而是模式匹配(因为在 Erlang 中没有赋值)。

          $ erl
          Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]
          
          Eshell V5.8.1  (abort with ^G)
          1> [H1, H2, H3| Rest] = [1,2,3,4,5].
          [1,2,3,4,5]
          2> H1.
          1
          3> H2.
          2
          4> H3.
          3
          5> Rest.
          [4,5]
          

          为什么叫“模式匹配”?因为它实际上是匹配模式。看:

          6> [1,2,3,4,A] = [1,2,3,4,5].
          [1,2,3,4,5]
          7> A.
          5
          8> [1,2,3,4,A] = [1,2,3,4,6].
          ** exception error: no match of right hand side value [1,2,3,4,6]
          

          在第一个中,我们所做的实际上相当于断言列表将以[1,2,3,4] 开头,并且第五个值可以是任何值,但请将其绑定到未绑定变量A。在第二个中,我们做了同样的事情,除了 A 现在被绑定了,所以我们明确地寻找列表 [1,2,3,4,5](因为 A 现在是 5)。

          【讨论】:

            【解决方案7】:

            Mozilla 称之为destructuring assignment。在 Python 中,它是sequence unpacking;元组拆包是一种常见的特殊情况。

            【讨论】:

              【解决方案8】:

              在 Clojure 中,它被称为解构。简单例子:

              (let [[foo bar] ["foo" "bar"]]
                (println "I haz" foo "and" bar))
              

              它也经常用于函数定义中,例如以下将单点参数解构为 x 和 y 分量:

              (defn distance-from-origin [[x y]]
                (sqrt (+ (* x x) (* y y))))
              

              您还可以使用相同的技术来解构嵌套数据结构或键/值关联映射。

              【讨论】:

                猜你喜欢
                • 2017-06-23
                • 1970-01-01
                • 2020-10-03
                • 1970-01-01
                • 2022-11-04
                • 2014-03-20
                • 1970-01-01
                • 2011-12-27
                • 2018-02-04
                相关资源
                最近更新 更多