使用什么样的Variadic功能?

时间:2011-12-13 17:14:24

标签: d variadic-functions

我想编写一个可变参数函数,它应该有1个参数,它不是string类型的可选参数,第二个字符串是可选的。我已经阅读了关于可变函数的语言规范,但考虑到D的许多选项我想知道哪个是我问题的合适解决方案。

另外我应该如何使用强制转换和指针来复制void* _argptr所指向的字符串(字符串在D中是不可变的这一事实让我感到困惑)。

编辑:我想要的是:

string foo (string nonopt, ...) { /*code*/ }

//...
string a = "x@a.t", b = "a.t";
auto s = foo(a);
auto s2 = foo(a, b);

5 个答案:

答案 0 :(得分:7)

你要求的东西根本没有变化。您确切地知道应该有多少个参数 - 1或2.在这种情况下,只需对第二个参数使用默认参数。 e.g。

void func(string required, string optional = null) {}

如果您想要的是string后跟未知数量的字符串,那么您可能想要做类似的事情

void func(string required, string[] optional...)

另一方面,如果您想要的是一个string后跟各种类型的未知数量的参数,那么您想要的是variadic template

void func(T...)(string required, T optional) {}

答案 1 :(得分:4)

你不喜欢这样的事情:

void foo(string required, string optional = "") {}

或者喜欢(未经测试):

class Optional(T) {
  private T _val;
  public this(in T val) { _val = val; }
  @property public T get() { return _val; }
}

void foo(string required, Optional!(string) = null) {}

答案 2 :(得分:3)

您可以执行C风格的可变参数功能,在这种情况下,请查看core.vararg。首选的D解决方案是使用模板化函数:

import std.stdio;

void foo(Args...)(string first, Args args)
{
    writeln("First argument is ", first);
    foreach (i, A; Args)
    {
        writefln("Type of %s argument is %s, value is %s",
                    i, A.stringof, args[i]);
    }
}

void main(){
    foo("bar", 1, 4.0, false);
}     

答案 3 :(得分:3)

这是一个foo()的例子,它完全按照你在OP中提出的要求加上可以接受任意数量参数的foovar()函数。在这种情况下,我只接受字符串参数,但您可以更改代码以接受任何内容。

import std.stdio;
import core.vararg;

string foo (string nonopt, string opt = "") {
  string ret;
  if (opt.length == 0)
    ret = nonopt;
  else
    ret = nonopt ~ ";" ~ opt;

  return ret;
} // foo() function

string foovar(string nonopt, ...) {
  string ret = nonopt ~ "/";
  for (int i = 0; i < _arguments.length; i++) {
    // we want to use only string arguments to build the result
    if (_arguments[i] == typeid(string)) {
      ret ~= va_arg!(string)(_argptr) ~ "/";
    } // if
  } // for
  return ret;
} // foovar() function

int main() {
  string a = "x@a.t", b = "a.t";
  auto s = foo(a);
  auto s2 = foo(a, b);
  auto s3 = foovar(a, "D", "rules");
  writeln(s);   // x@a.t
  writeln(s2);  // x@a.t;a.t
  writeln(s3);  // x@a.t/D/rules/
  return 0;
} //  main() function

答案 4 :(得分:2)

以下不会这样做吗?

void myFunction(string nonOptionalParameter, string optionalParameter="default value")
{
  // Your code here
}