【问题标题】:Are there any programming languages with functions with variable arguments not at the end?是否有任何编程语言的函数末尾没有可变参数?
【发布时间】:2010-09-28 03:31:52
【问题描述】:

Python、C++、Scheme 等都允许您定义在参数列表末尾采用可变数量参数的函数...

def function(a, b, *args):
    #etc...

...可以这样调用:

function(1, 2)
function(1, 2, 5, 6, 7, 8)

等... 是否有任何语言允许您在其他地方使用参数列表执行可变参数函数?像这样的:

def function(int a, string... args, int theend) {...}

所有这些都有效:

function(1, 2)
function(1, "a", 3)
function(1, "b", "c", 4)

另外,参数列表中任意位置的可选参数呢?

def function(int a, int? b, int c, int... d) {}

function(1, 2) //a=1, c=2, b=undefined/null/something, d=[]
function(1,2,3) //a=1, b=2, c=3,d=[]
function(1,2,3,4,5) //a=1, b=2, c=3, d=[4,5]

【问题讨论】:

  • 为什么不直接使用数组\集合?
  • 你可以。那么为什么在 Python/C++ 中有 *args 呢?人们似乎喜欢他们。
  • 语法糖恕我直言;但每个人都有自己的:)

标签: programming-languages function arguments variadic-functions


【解决方案1】:

几种语言(perl,python,许多其他语言)可以做命名参数,这类似于在参数列表中的任何地方做可选参数......(命名参数可以以任何顺序出现,并且可以制作任何一个可选...)它们并不完全相同,但它们很接近...

不确定可变参数,尽管它们通常可以替换为数组/哈希/列表对象...

【讨论】:

    【解决方案2】:

    它被称为 Rest Arguments,至少可以在 C++ 和 Java 中完成。谷歌“Rest Arguments”,你会发现很多关于这个主题的数据,比如一些例子,比如传递数字并返回输入数字的平均值,可能是传递的所有数字的最小值或最大值。如您所见,这些功能有很多用途,我在代码中使用它在 MYSQL 中输入数据,所以当我想添加一行时,我只需将表名称添加为第一个字符串,其余的都是列名称,然后是他们的数据,而不必坐在那里一遍又一遍地手动执行。祝你好运!

    【讨论】:

      【解决方案3】:

      R(统计语言)也有它,它可以在列表的中间,但有微妙的语义。

      http://cran.r-project.org/doc/manuals/R-intro.html#The-three-dots-argument

      > f1 <- function(x,...,y) {  return(x+y) }
      > f1(1,2)
      Error in f1(1, 2) : argument "y" is missing, with no default
      > f1(1,y=2)
      [1] 3
      > f1 <- function(x,...,y) {  return(x+y) }
      > f1(1,2)
      Error in f1(1, 2) : argument "y" is missing, with no default
      > f1(1,y=2)
      [1] 3
      > 
      

      【讨论】:

        【解决方案4】:

        BASIC 已经有很多年了。

        例如:

        LOCATE [row%] [,[column%] [,[cursor%] [,start% [,stop%]]]]
        

        该命令设置游标的位置(行%、列%),以及指定游标大小(开始%、停止%)和是否实际可见(游标%)。在这里,方括号中的所有内容都可以省略,如果是,则该属性不会更改。

        使用示例:

        LOCATE , 5
        

        更改为第 5 列,或

        LOCATE 1, , 0
        

        移动到第一行并使光标不可见。

        另一个可以看到这种情况的命令是用于写入文件的 PUT 命令。如果中间参数(文件查找位置)被省略,则写入发生在前一次写入之后。

        重要的是,参数省略只出现在内置语句中,而不是用户定义的过程和函数。

        在实现方面,这是 Microsoft Basic Compiler (BC) 似乎对 LOCATE 的调用所做的:

        1. 对于每个参数:
          • 如果省略参数,则按 0
          • 如果提供了参数,则压入 1,然后压入实际值
        2. 推送参数计数
        3. 调用库函数

        【讨论】:

          【解决方案5】:

          Ruby 的未来版本(1.9 及更高版本,Ruby 1.9 计划于 2009 年 1 月末发布)可以做到这一点。

          然而,哪个值绑定到哪个参数并不总是很明显。

          这是 Ruby 1.9 接受的:

          0 个或多个强制参数,后跟 0 个或多个可选参数,后跟 0 个或多个强制参数,后跟其余参数,后跟 0 个或多个强制参数。

          例子:

          def meth mand1, opt1 = :def1, o2 = :d2, *args, m2, m3
            puts %w[mand1 opt1 o2 m2 args m3].inject('') { |s, arg|
              s << "#{arg} = #{(eval arg).inspect}, "
            }.gsub /, $/, ''
          end
          
          meth :arg1, :a2, :a3
          # => mand1 = :arg1, opt1 = :def1, o2 = :d2, m2 = :a2, args = [], m3 = :a3
          meth :arg1, :a2, :a3, :a4
          # => mand1 = :arg1, opt1 = :a2, o2 = :d2, m2 = :a3, args = [], m3 = :a4
          meth :arg1, :a2, :a3, :a4, :a5
          # => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a4, args = [], m3 = :a5
          meth :arg1, :a2, :a3, :a4, :a5, :a6
          # => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a5, args = [:a4], m3 = :a6
          meth :arg1, :a2, :a3, :a4, :a5, :a6, :a7
          # => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a6, args = [:a4, :a5], m3 = :a7
          

          如您所见,强制参数首先从左侧和右侧绑定。然后绑定可选参数,如果剩余任何参数,它们将捆绑在一个数组中并绑定到其余参数。

          【讨论】:

          • 天哪,Ruby 语法高亮异常很糟糕,即使是 prettify.js。
          【解决方案6】:

          下一个 C++ 可以用这种语法做到这一点:

          void f(int a, std::initializer_list<int> b, int c) {
              // b.begin(), b.end(), b.size() allow to access them
          }
          
          void g() { 
              f(1, { 2, 3, 4, 5 }, 2);
          }
          

          【讨论】:

          • 是的,碰巧,C++ 有一个版本 :) 看起来新版本将在 2010 年发布。您可以使用已经支持它们的当前 gcc 主干使用初始化列表(至少同意你可以编译和使用上面的代码):)
          • 我认为在这个例子中 b 只是一个论点。并且在函数 g 中,使用三个参数调用 f:1、{2,3,4,5} 和 2。
          【解决方案7】:

          我想 PHP 很重要。您可以这样做来模拟您正在寻找的内容。就个人而言,我认为这会令人困惑。

          function foo() {
              $args = func_get_args(); // returns an array of args
          }
          

          【讨论】:

            【解决方案8】:

            Lisp's keyword parameters 可能就是您要找的。我认为在 Ruby 中也有类似的安排。另见Lisp's function parameters overview

            【讨论】:

              猜你喜欢
              • 2018-12-09
              • 1970-01-01
              • 1970-01-01
              • 2019-12-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-19
              相关资源
              最近更新 更多