使用什么样的可变参数函数?

发布于 2024-12-21 01:08:14 字数 472 浏览 1 评论 0原文

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

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

编辑:我想要的是:

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

//...
string a = "[email protected]", b = "a.t";
auto s = foo(a);
auto s2 = foo(a, b);

I want to write a variadic function that should have 1 parameter that is not optional of type string and a second string that is optional. I have read the language spec about variadic functions but considering D's many options I would like to know which is the appropriate solution for my problem.

Also how should I use cast and pointer for copying the string pointed by the void* _argptr (the fact that strings are immutable in D confuses me I guess).

Edit: What I want is something like:

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

//...
string a = "[email protected]", b = "a.t";
auto s = foo(a);
auto s2 = foo(a, b);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千寻… 2024-12-28 01:08:14

你所要求的听起来一点也不可变。您确切地知道应该有多少个参数 - 1 或 2。在这种情况下,只需使用第二个参数的默认参数。例如,

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

如果您想要的是一个 string 后跟未知数量的字符串,那么您可能想要执行类似

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

If 的操作,另一方面,您想要的是需要 >string 后跟未知数量的各种类型的参数,那么您想要的是 可变参数模板

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

What you're asking for doesn't sound variadic at all. You know exactly how many arguments there are supposed to be - either 1 or 2. In that case, just use a default argument for the second parameter. e.g.

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

If what you want is a string followed by an unknown number of strings, then you'd probably want to do something like

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

If, on the other hand, what you want is something which takes a string followed by an unknown number of arguments of a variety of types, then what you want is a variadic template.

void func(T...)(string required, T optional) {}
智商已欠费 2024-12-28 01:08:14

你想要类似的东西吗:

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) {}

Do you wan't something like:

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

Or maybe like (not tested):

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) {}
望她远 2024-12-28 01:08:14

下面是一个 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 = "[email protected]", b = "a.t";
  auto s = foo(a);
  auto s2 = foo(a, b);
  auto s3 = foovar(a, "D", "rules");
  writeln(s);   // [email protected]
  writeln(s2);  // [email protected];a.t
  writeln(s3);  // [email protected]/D/rules/
  return 0;
} //  main() function

Here is an example with foo() that does exactly what you asked in the OP, plus the foovar() function which can take arbitrary number of parameters. In this case I accept only string arguments, but you may change the code to accept anything.

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 = "[email protected]", b = "a.t";
  auto s = foo(a);
  auto s2 = foo(a, b);
  auto s3 = foovar(a, "D", "rules");
  writeln(s);   // [email protected]
  writeln(s2);  // [email protected];a.t
  writeln(s3);  // [email protected]/D/rules/
  return 0;
} //  main() function
西瓜 2024-12-28 01:08:14

您可以执行 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);
}     

You can do a C-style variadic function, in which case check out core.vararg. The preferred D solution is to use a templated function:

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);
}     
伴随着你 2024-12-28 01:08:14

下面的做法不行吗?

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

Would the following not do?

void myFunction(string nonOptionalParameter, string optionalParameter="default value")
{
  // Your code here
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文