我的函数采用字典参数和可变数量的NSString变量。所有这些组合都放入一个[NSString stringWithFormat:]方法中,并作为NSURLRequest. 该方法如下所示:
- (NSURLRequest *)buildPath:(NSString *)stringPath attributes:(NSString *)attribute, ...
{
va_list list;
NSString *eachObject;
NSMutableArray *args = [NSMutableArray array];
[args addObject:attribute];
va_start(list, attribute);
while ((eachObject = va_arg(list, NSString *))) {
[args addObject:eachObject];
}
va_end(list);
NSString *listOfAttributes = [args componentsJoinedByString:@", "];
NSString *pathURL = _requestString[stringPath];
NSString *path = [NSString stringWithFormat:pathURL, listOfAttributes];
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
return request;
}
Run Code Online (Sandbox Code Playgroud)
这是我调用该方法时的样子:
NSURLRequest *request = [_venueService buildPath:@"categories"
attributes:_venueService.clientID, _venueService.clientSecret, _venueService.todaysDate, nil]; …Run Code Online (Sandbox Code Playgroud) objective-c variadic-functions nsstring stringwithformat ios
J. Bloch在《Effective Java》中提到,对原始类型使用 varargs 方法是不安全的。准确地说,Arrays.asList(1, 2, 4)有返回类型List<int[]>,听起来很合理。现在我尝试自己重现这种行为,但无法:
我的问题是为什么类型被推导为List<Integer>而不是List<int[]>如他所说的那样?这是否意味着,在 Java 8 中,有关 varargs 的问题不再相关,如果我们不太关心性能,我们可以在任何我们想要的地方安全地使用它们。
我正在尝试使用以下签名从 Swift 调用 C 函数(外部 API):
extern void k(int, const char*, ...)
Run Code Online (Sandbox Code Playgroud)
我这样调用 C 函数:
func send(query: String, args: CVarArg...) {
let query2 = UnsafeMutablePointer(mutating: query.cString(using: String.defaultCStringEncoding))
let result = k(0, query2, args)
}
Run Code Online (Sandbox Code Playgroud)
但出现错误'k' is unavailable: Variadic function is unavailable。
我不确定这是否可行,因为 C API 不接受va_list( http://swiftdoc.org/v3.1/protocol/CVarArg/ )。如果需要的话,我不介意用 C 语言编写包装函数。
请让我知道是否有办法在宏函数中使用变量参数并使下面的宏代码工作。
换句话说,有什么方法可以在 va_start 中使用局部变量。
typedef struct
{
char *p1;
char *p2;
char *p3;
}Pointers;
#define NULLCHECK_VR(num, ...) \
{ \
va_list valist; \
int v_index; \
\
va_start(valist, num); \
\
for( v_index=0; v_index < num; v_index++) \
{ \
if( NULL == va_arg(valist, void *)) \
{ \
printf("NULL \n"); \
} \
else \
{ \
printf("NOT NULL \n"); \
} \
} \
\
va_end(valist); \
}
int main(void)
{
Pointers ptr;
memset(&ptr, 0, sizeof(Pointers));
NULLCHECK_VR(3, ptr.p1, …Run Code Online (Sandbox Code Playgroud) 当我调用时a.displayName("Test"),它调用 Icecream 类的方法。displayName(String...s)方法接受可变参数。输出-
test Icecream
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
Run Code Online (Sandbox Code Playgroud)
但是当我将方法更改为displayName(String s)(我已经在代码中注释掉了该部分)时,它会调用 Faloodeh 类的方法。新输出-
test Faloodeh
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
Run Code Online (Sandbox Code Playgroud)
我想知道为什么会这样。
class Icecream{
public void displayName(String...s){
System.out.println(s[0]+" "+"Icecream");
}
/*public void displayName(String s){
System.out.println(s+" "+"Icecream");
}
*/
public void describe(String s) {
System.out.println(s+" "+"Icecream: Ice cream");
}
}
class Faloodeh extends Icecream {
public void displayName (String s){
System.out.println(s+" "+"Faloodeh ");
}
public void describe (String s) …Run Code Online (Sandbox Code Playgroud) 您好,我想将一个结构传递给可变参数函数,并在 C 中使用所述结构内的值。我不知道该怎么做是如何访问传递的每个结构的内容。
这是一个示例情况
typedef struct {
int num;
bool dontIncludeFlag;
} number;
int average(unsigned count, ...){
va_list ap;
int j;
int sum = 0;
va_start(ap, count);
for (j = 0; j < count; j++) {
if(va_arg(ap,number.dontIncludeFlag)) //This line does not work
sum += va_arg(ap.num, number); //so does this line
}
va_end(ap);
return sum / count;
}
int main(){
number a,b,c;
a.num= 5;
a.dontIncludeFlag = 0;
b.num= 2;
b.dontIncludeFlag= 1;
c.num= 1;
c.dontIncludeFlag= 0;
average(3,a,b,c);
}
Run Code Online (Sandbox Code Playgroud)
如何访问我传递的结构参数的内容
我是 Julia 的新手,对 R 有更多的经验,所以对于那些熟悉两者的人,这里是我试图在 Julia 中复制的一段 R 代码。
f = function(a, b = 1, c = 2) a + 2*b = 3*c
g = function(d, ...) 5 + f(d, ...)
Run Code Online (Sandbox Code Playgroud)
有了这个,调用 将是有效的g(1),它将使用 f 的默认值进行评估,或者您可以指定g(1, b = 3)org(1, c = 4, b = 2)或其他任何内容。重点当然是,只要指定了名称,您就可以将可选参数的任何排列传递给 f,而顺序无关紧要。
在 Julia 中,我在这样做时遇到了一些麻烦,因为 varargs 的工作方式有点不同。我知道您可以将无限的参数列表以元组(例如,function g(d::Number, f_args::NamedTuple)的形式传递给函数,但它似乎不适用于可选的关键字参数。就好像在这条线的某个地方,f_args元组失去了它的名字,并且f因为它看到 3 个没有名字的参数并且不知道选择哪个方法而感到困惑?
如果确实可能的话,如果有人能告诉我如何在 Julia 中做到这一点,我将不胜感激。我想保留这些参数的可选性,以及它们的名称。我还希望能够保留它们的类型(即,我希望 的每个参数f只有在它们适合正确的类型时才可以接受,这当然通常在 Julia 中使用::标头中的运算符完成)。
PS - 就我的问题而言,重写g …
我想知道是否可以在 C 或汇编中实现可变参数宏。
我希望至少 va_start() 是一个 C 宏,但看起来这可能不可能。我看过不同问题的其他答案,说在 C 中不可能做到这一点,因为你必须依赖未定义的行为。
就上下文而言,我正在编写一个内核,我不想依赖任何特定的 C89 编译器或类 UNIX 汇编器。使用任何 C 编译器构建源代码对于该项目都很重要。保持简单是另一个目标,不幸的是,支持诸如可变参数之类的东西在某些架构(amd64 ABI)上似乎很复杂。
我知道 __builtin_va_start(v,l)、__builtin_va_arg(v, l) 等宏存在,但这些仅适用于特定编译器?
现在我有用汇编(i386 ABI)编写的内核 printf(, ...) 和panic(, ...) 例程,它们设置 va_list (指向堆栈上第一个 va 参数的指针)并将其传递给 vprintf(, va_list),然后使用 va_arg() 宏(用 C 语言编写)。这不依赖于任何未定义或实现定义的行为,但我更喜欢所有宏都用 C 编写。
我试图通过将值传递va_arg给数组来通过变量参数修改数组,但由于某种原因它给出了奇怪的结果,这是代码:
#include <stdio.h>
#include <stdarg.h>
void get_args(double* args, int argc, ...);
void get_args(double* args, int argc, ...) {
va_list argv;
va_start(argv, argc);
if (argc == 1) {
args[0] = va_arg(argv, double);
}
else if (argc == 4) {
for (int i = 0; i < argc; i++) {
args[i] = va_arg(argv, double);
}
}
va_end(argv);
}
int main(void) {
double args[4] = { 0, 0, 0, 0 };
get_args(args, 4, 0, 1, 2, 3);
for (int i = …Run Code Online (Sandbox Code Playgroud) 这是我的函数的代码:
#include <iostream>
#include <type_traits>
#include <algorithm>
template <typename Head, typename ... Args>
std::common_type_t<Head, Args...> mx(Head n, Args ... args)
{
if (sizeof ... (args) == 0)
return n;
else
return std::max(n, mx(args ...));
}
int main()
{
std::cout << mx(3, 4, 5);
}
Run Code Online (Sandbox Code Playgroud)
我遇到编译错误:
main.cpp:在 'std::common_type_t<Head, Args ...> mx(Head, Args ...) 的实例化中 [with Head = int; 参数 = {}; std::common_type_t<Head, Args ...> = int]': main.cpp:11:24:
从 'std::common_type_t<Head, Args ...> mx(Head, Args ...) 递归地需要[头= int; 参数 = {int}; std::common_type_t<Head, Args …