Какую функцию Variadic использовать? - PullRequest
1 голос
/ 13 декабря 2011

Я хочу написать переменную функцию, которая должна иметь 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 ]

7 голосов
/ 14 декабря 2011

То, что вы просите, вовсе не звучит вариативно.Вы точно знаете, сколько аргументов должно быть - 1 или 2. В этом случае просто используйте аргумент по умолчанию для второго параметра.например,

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

Если вам нужно string, за которым следует неизвестное количество строк, то вы, вероятно, захотите сделать что-то вроде

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

Если нас другой стороны, то, что вам нужно, - это то, что требует string, за которым следует неизвестное количество аргументов различных типов, тогда вам нужен шаблон с переменным числом .

void func(T...)(string required, T optional) {}
4 голосов
/ 13 декабря 2011

Ты не хочешь что-то вроде:

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) {}
3 голосов
/ 14 декабря 2011

Вот пример с 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
3 голосов
/ 13 декабря 2011

Вы можете сделать функцию с переменным числом в стиле 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);
}     
2 голосов
/ 13 декабря 2011

Не подойдет ли следующее?

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