Как перенести функцию с аргументами переменной длины?

Поскольку swift в некоторых отношениях более функциональна, чем объектно-ориентированная (а массивы - это структуры, а не объекты), используйте функцию «find» для работы с массивом, которая возвращает необязательное значение, поэтому будьте готовы обрабатывать нуль Значение:

let arr:Array = ["a","b","c"]
find(arr, "c")!              // 2
find(arr, "d")               // nil

Обновление для Swift 2.0:

Старая функция find больше не поддерживается с Swift 2.0!

С Swift 2.0 Array получает возможность находить индекс элемента, используя функцию, определенную в расширении CollectionType (который реализуется Array):

let arr = ["a","b","c"]

let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil

Дополнительно , поиск первого элемента в массиве, выполняющем предикат, поддерживается другим расширением CollectionType:

let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil

Обратите внимание, что эти две функции возвращают необязательные значения, как это делал ранее find.

Обновление для Swift 3.0:

Обратите внимание, что синтаксис indexOf изменился. Для элементов, соответствующих Equatable, вы можете использовать:

let indexOfA = arr.index(of: "a")

Подробную документацию по этому методу можно найти на странице https://developer.apple.com/reference/swift/array/ 1689674-index

Для элементов массива, которые не соответствуют Equatable, вам нужно будет использовать index(where:):

let index = cells.index(where: { (item) -> Bool in
  item.foo == 42 // test if this is the item you're looking for
})

46
задан Richard Hansen 9 February 2015 в 03:42
поделиться

4 ответа

проблема состоит в том, что Вы не можете использовать 'printf' с va_args. Необходимо использовать vprintf при использовании списков аргумента переменной. vprint, vsprintf, vfprintf, и т.д. (существуют также 'безопасные' версии во времени выполнения Microsoft C, которое предотвратит переполнение буфера, и т.д.)

, Вы выбираете работы следующим образом:

void myprintf(char* fmt, ...)
{
    va_list args;
    va_start(args,fmt);
    vprintf(fmt,args);
    va_end(args);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 9;
    int b = 10;
    char v = 'C'; 
    myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b);
    return 0;
}
65
ответ дан Arun 26 November 2019 в 20:25
поделиться

Я также не уверен, под чем Вы подразумеваете чистый

В C++, который мы используем

#include <cstdarg>
#include <cstdio>

class Foo
{   void Write(const char* pMsg, ...);
};

void Foo::Write( const char* pMsg, ...)
{
    char buffer[4096];
    std::va_list arg;
    va_start(arg, pMsg);
    std::vsnprintf(buffer, 4096, pMsg, arg);
    va_end(arg);
    ...
}
8
ответ дан David Sykes 26 November 2019 в 20:25
поделиться

Вы используете C или C++? Следующая версия C++, C++ 0x, будет поддерживать шаблоны variadic , которые предоставляют решение той проблемы.

Другое обходное решение может быть достигнуто умным оператором, перегружающимся для достижения синтаксиса как это:

void f(varargs va) {
    BOOST_FOREACH(varargs::iterator i, va)
        cout << *i << " ";
}

f(args = 1, 2, 3, "Hello");

, Чтобы заставить это работать, класс varargs должен быть реализован для переопределения operator =, который возвращает объект прокси, который, в свою очередь, переопределяет operator ,. Однако создание этого варианта, безопасного с точки зрения типов в текущем C++, не возможно, насколько я знаю, так как это должно было бы работать стиранием типа.

1
ответ дан Konrad Rudolph 26 November 2019 в 20:25
поделиться

Как Вы имеете в виду чистое решение для C/C++?

Остальные параметр (...) поддерживается кросс-платформенный во времени выполнения C.

http://msdn.microsoft.com/en-us/library/kb57fad8.aspx

0
ответ дан Mark Ingram 26 November 2019 в 20:25
поделиться