D - 如果可变参数无法正常工作则为静态
D - static if on variadic arguments not working properly
假设我有以下可变参数函数,它的工作是将片段拼接在一起(每个片段可以是整数类型的索引,也可以是字符串类型的节点):
string
makePath(P...)(P path)
{
import std.conv;
import std.format;
string res;
foreach (piece; path) {
pragma(msg, typeof(piece).stringof);
static if (is(piece: size_t))
res = res is null ? piece.to!string : format("%s[%s]", res, piece);
else if (is(piece: string))
res = res is null ? piece : format("%s.%s", res, piece);
else
static assert(0);
}
}
如果我以后像这样使用它:string path = makePath("foo", "bar")
,代码会以某种方式到达 static assert(0);
并且编译终止。这是最好奇的,但 pragma 实际上将 string
写为第一个参数的类型,尽管事实上采用了其他类型的代码路径。
更好的是,使用 makePath(12, 13)
会导致编译器抱怨 both strings 的行(关于不兼容的类型int
和 string
) 和 static assert
。这是怎么回事?
我在 DMD 和 LDC 上都试过了。
is
关键字是这里的错误所在。 (我发现这是一个相当令人困惑的关键字......)
我建议您使用 std.traits 中的模板来测试类型,大多数都涵盖了:https://dlang.org/phobos/std_traits.html
这是您函数的工作版本:
string
makePath(P...)(P path)
{
import std.conv;
import std.format;
import std.traits : isSomeString, isNumeric;
string res;
foreach (piece; path) {
static if (isNumeric!(typeof(piece)))
res = res is null ? piece.to!string : format("%s[%s]", res, piece);
else static if (isSomeString!(typeof(piece))) // Note, you were missing the 'static' on the 'else if' part
res = res is null ? piece : format("%s.%s", res, piece);
else
static assert(0);
}
return res;
}
unittest {
static assert(makePath("foo","bar") == "foo.bar");
static assert(makePath("foo","bar",1) == "foo.bar[1]");
}
假设我有以下可变参数函数,它的工作是将片段拼接在一起(每个片段可以是整数类型的索引,也可以是字符串类型的节点):
string
makePath(P...)(P path)
{
import std.conv;
import std.format;
string res;
foreach (piece; path) {
pragma(msg, typeof(piece).stringof);
static if (is(piece: size_t))
res = res is null ? piece.to!string : format("%s[%s]", res, piece);
else if (is(piece: string))
res = res is null ? piece : format("%s.%s", res, piece);
else
static assert(0);
}
}
如果我以后像这样使用它:string path = makePath("foo", "bar")
,代码会以某种方式到达 static assert(0);
并且编译终止。这是最好奇的,但 pragma 实际上将 string
写为第一个参数的类型,尽管事实上采用了其他类型的代码路径。
更好的是,使用 makePath(12, 13)
会导致编译器抱怨 both strings 的行(关于不兼容的类型int
和 string
) 和 static assert
。这是怎么回事?
我在 DMD 和 LDC 上都试过了。
is
关键字是这里的错误所在。 (我发现这是一个相当令人困惑的关键字......)
我建议您使用 std.traits 中的模板来测试类型,大多数都涵盖了:https://dlang.org/phobos/std_traits.html
这是您函数的工作版本:
string
makePath(P...)(P path)
{
import std.conv;
import std.format;
import std.traits : isSomeString, isNumeric;
string res;
foreach (piece; path) {
static if (isNumeric!(typeof(piece)))
res = res is null ? piece.to!string : format("%s[%s]", res, piece);
else static if (isSomeString!(typeof(piece))) // Note, you were missing the 'static' on the 'else if' part
res = res is null ? piece : format("%s.%s", res, piece);
else
static assert(0);
}
return res;
}
unittest {
static assert(makePath("foo","bar") == "foo.bar");
static assert(makePath("foo","bar",1) == "foo.bar[1]");
}