我想编写一个可变参数函数,它应该有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);
答案 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
}