Vala varargspassing 属性: 值对
Vala varargspassing property: value pairs
在 Variable-Length Argument Lists 的 Vala 项目教程中,显示了一种调用技术:
A common pattern with varargs is to expect alternating string - value pairs as arguments, usually meaning gobject property - value. In this case you can write property: value instead, e.g.:
actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, x: 100.0, y: 200.0, rotation_angle_z: 500.0, opacity: 0);
is equivalent to:
actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, "x", 100.0, "y", 200.0, "rotation-angle-z", 500.0, "opacity", 0);
我该如何解码?文中展示的代码是比较正常的全逗号参数传递。它没有正确解码备用样式。
我尝试了给出的示例代码:
void method_with_varargs(int fixed, ...) {
var l = va_list();
while (true) {
string? key = l.arg();
if (key == null) {
break; // end of the list
}
double val = l.arg();
stdout.printf("%s: %g\n", key, val);
}
}
并打印
x: 0
rotation_angle_z: 0
如果我取出双 val
void method_with_varargs(int fixed, ...) {
var l = va_list();
while (true) {
string? key = l.arg();
if (key == null) {
break; // end of the list
}
stdout.printf("%s: \n", key);
}
}
它打印
x:0
y:0
rotation_angle_z: 0
opacity: 0
我猜这需要是不同于字符串的类型,但是什么?
string? key = l.arg();
如果不显示确切的函数调用,则很难确定,但我猜你正在将 int 混合到调用方。 0
与 0.0
不同;前者是 int,后者是 double。通常,整数是 32 位而双精度数是 64 位,所以如果你传递一个整数但试图将它读作双精度数(反之亦然),事情就会变得不同步并且不仅会破坏当前参数而且会破坏未来参数还有。
基本上,要么确保所有值参数的类型相同,要么将不同键的值分配给正确类型的变量(即 if (key == "opacity") { uint val = l.arg(); } else { double val = l.arg(); }
)。
对于像Clutter.Actor.animate()
这样的函数,类型是通过查找相关的GObject来确定的属性。 x, y, and rotation-angle-z are all floats, and opacity 是一个单位。当传递给可变参数函数时,浮点数被提升为双精度(我实际上不记得 C 是否指定了这个或者它只是所有 x86 调用约定)这就是 0.0
按预期工作的原因,但它可能更正确使用 0.0f
作为浮点参数,使用 0.0
作为双精度参数。
当使用可变参数时(在 C 和 Vala 中)你必须记住你失去了类型安全。你必须非常小心你传递的是什么类型,因为编译器不能告诉你什么时候你搞砸了。
在 Variable-Length Argument Lists 的 Vala 项目教程中,显示了一种调用技术:
A common pattern with varargs is to expect alternating string - value pairs as arguments, usually meaning gobject property - value. In this case you can write property: value instead, e.g.: actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, x: 100.0, y: 200.0, rotation_angle_z: 500.0, opacity: 0);
is equivalent to:
actor.animate (AnimationMode.EASE_OUT_BOUNCE, 3000, "x", 100.0, "y", 200.0, "rotation-angle-z", 500.0, "opacity", 0);
我该如何解码?文中展示的代码是比较正常的全逗号参数传递。它没有正确解码备用样式。
我尝试了给出的示例代码:
void method_with_varargs(int fixed, ...) {
var l = va_list();
while (true) {
string? key = l.arg();
if (key == null) {
break; // end of the list
}
double val = l.arg();
stdout.printf("%s: %g\n", key, val);
}
}
并打印
x: 0
rotation_angle_z: 0
如果我取出双 val
void method_with_varargs(int fixed, ...) {
var l = va_list();
while (true) {
string? key = l.arg();
if (key == null) {
break; // end of the list
}
stdout.printf("%s: \n", key);
}
}
它打印
x:0
y:0
rotation_angle_z: 0
opacity: 0
我猜这需要是不同于字符串的类型,但是什么?
string? key = l.arg();
如果不显示确切的函数调用,则很难确定,但我猜你正在将 int 混合到调用方。 0
与 0.0
不同;前者是 int,后者是 double。通常,整数是 32 位而双精度数是 64 位,所以如果你传递一个整数但试图将它读作双精度数(反之亦然),事情就会变得不同步并且不仅会破坏当前参数而且会破坏未来参数还有。
基本上,要么确保所有值参数的类型相同,要么将不同键的值分配给正确类型的变量(即 if (key == "opacity") { uint val = l.arg(); } else { double val = l.arg(); }
)。
对于像Clutter.Actor.animate()
这样的函数,类型是通过查找相关的GObject来确定的属性。 x, y, and rotation-angle-z are all floats, and opacity 是一个单位。当传递给可变参数函数时,浮点数被提升为双精度(我实际上不记得 C 是否指定了这个或者它只是所有 x86 调用约定)这就是 0.0
按预期工作的原因,但它可能更正确使用 0.0f
作为浮点参数,使用 0.0
作为双精度参数。
当使用可变参数时(在 C 和 Vala 中)你必须记住你失去了类型安全。你必须非常小心你传递的是什么类型,因为编译器不能告诉你什么时候你搞砸了。