2015-03-26 2 views
1

У меня есть следующая функция, которая читает некоторые данные сердечного ритма и принимает функцию обратного вызова в виде закрытия, как таковой:Как необязательно передать значения закрытию в Swift?

func readHeartRate(callback: ((samples: [HKQuantitySample]?, average: Double?, error: NSError!) -> Void)!){ 
    // ... 
    // ERROR - call the callback with no samples or average 
    callback(samples: nil, average: nil, error: error) 
}) 

Прямо сейчас, я явно передавая обратно nil для samples и average к Перезвони.

Однако, поскольку samples и error не являются обязательными, и так как я объявил имена в закрытии явно, я думал, что это было бы возможно, вместо этого:

callback(error: error) 

Однако, когда я делаю это Xcode жалуется и броски ошибка:

Missing argument for parameter 'samples' in call 

Есть ли способ вызвать обратный вызов только с необходимыми значениями, чтобы избежать загромождения кода?

ответ

3

Для обычного метода, вы можете указать значение по умолчанию для параметра:

func myCallback(#error: NSError!, samples: [HKQuantitySample]? = nil, average: Double? = nil) { 
} 

myCallback(error: nil) 

Эти параметры со значениями по умолчанию должны быть в конце списка аргументов.

Это не работает в вашем случае, так как вы не определяете метод; вы просто указываете подпись метода, которую вызывающие должны передать для обратного вызова. Например, вы можете сказать «передать метод, который принимает Int», но в настоящее время нет способа сказать «передать метод, который принимает Int, а использует значение по умолчанию 0, если я ничего не пропускаю в" ,

Помните, что необязательные значения просто означают, что наличие значения является необязательным, а вещь может быть равна нулю.

+0

«Эти параметры со значениями по умолчанию должны быть в конце списка аргументов». - это выполняется только для неназванных параметров, т. е. если вы назвали params, любой из них может иметь значение по умолчанию. –

+0

Это больше для согласованности, чтобы поддерживать порядок аргументов одинаковым. «Поместите параметры со значениями по умолчанию в конце списка параметров функции. Это гарантирует, что все вызовы функции будут использовать один и тот же порядок для своих аргументов, отличных от параметров по умолчанию, и дадут понять, что в каждом случае вызывается одна и та же функция». - [Быстрый язык программирования] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID166) – gregheo

+0

Вы правы, мне плохо. Я принял его за императив вместо рекомендации, но «должен» правильно выражать смысл. –

3

От The Swift Programming Language:

Closure expression syntax can use constant parameters, variable parameters, and inout parameters. Default values cannot be provided. Variadic parameters can be used if you name the variadic parameter and place it last in the parameter list.

Так единственный способ, чтобы иметь возможность вызвать закрытие с переменным числом заданных параметров является использование VARIADIC Params, который - я полагаю, - это не то, что вы хотите.

0

У меня были случаи, когда я решил обернуть замыкание функцией, чтобы я мог предоставить параметр по умолчанию. Вот как это работает:

let myClosure: String ->() = { string in 
    println(string) 
} 

func myFunc(string: String = "default") { 
    myClosure(string) 
} 

myFunc()  // prints "default" 

Я знаю, что ваша цель состоит в том, чтобы «Declutter» ваш код, так ли или не писать функции оболочки является то, что вы хотите, я не знаю, но это работает.