ios - schemes - ¿Se pueden establecer los cierres rápidos en un valor predeterminado cuando se utiliza como parámetro en una función?
url scheme ios (3)
Una característica bastante útil de las funciones de Swift es que los parámetros de la función pueden tener valores predeterminados :
func someFunction(parameterWithDefault: Int = 42) {
//if no arguments are passed to the function call,
//value of parameterWithDefault is 42
}
Si un parámetro es un cierre, ¿hay alguna manera de hacer que tenga un valor predeterminado? Vea el ejemplo a continuación:
func sendBody(
body: NSData? = nil,
success: (data: NSData) -> Void,
failure: (data: NSData?) -> Void) {
}
¿Hay una manera de no forzar al desarrollador a pasar un valor para el success
o el failure
al llamar a sendBody
?
Mi forma preferida de especificar cierres de cara al público, en particular los cierres de finalización que quizás desee almacenar en algún lugar para más adelante, es definir una typealias
para ellos, como esta:
public typealias FooCompletion = (String) -> Void
Luego, en la función orientada al público, puedes hacerlo fácilmente como opcional:
var onCompletion: FooCompletion? = nil
public func foo(completion: FooCompletion? = nil) {
// Store completion for later
onCompletion = completion
}
El parámetro de completion
es opcional, por lo que puede ser nil
, y el valor predeterminado es nil
, lo que significa que la persona que llama no tiene que especificarlo. Además, debido a que usa el tipo en más de un lugar, si necesita cambiar su definición durante el desarrollo, solo hay un lugar para hacerlo. Es fácil llamar también:
private func someBackgroundThing() {
var completionString = "done"
...
onCompletion?(completionString)
}
Podrías hacer algo como esto,
let defaultSuccess: NSData -> Void = {
(data: NSData) in
}
let defaultFailure: NSData? -> Void = {
(data: NSData?) in
}
func sendBody( body: NSData? = nil, success: (data: NSData) -> Void = defaultSuccess, failure: (data: NSData?) -> Void = defaultFailure) {
}
Entonces, puede ser capaz de llamar a cualquiera de estos métodos. Observe sendBody que se llama con los parámetros por defecto.
sendBody()
sendBody(body: , success: , failure: )
También puede llamar con todas las variantes como pasar solo uno de los argumentos en el método anterior, para eso tiene que llamarlo con un parámetro con nombre.
sendBody()
sendBody(body:)
sendBody(failure: )
sendBody(success:)
sendBody(body: , success: , failure: )
Sí, las funciones son solo valores que usted puede proporcionar como valores predeterminados:
// just to show you can do it with inline closures or regular functions
func doNothing<T>(t: T) -> Void { }
func sendBody(
body: NSData? = nil,
success: (data: NSData) -> Void = { _ in return },
failure: (data: NSData?) -> Void = doNothing
)
{ }
Alternativamente, puede hacer que sean opcionales, de esa manera puede detectar si la persona que llama pasó uno:
func sendBody(
body: NSData? = nil,
success: ((NSData) -> Void)? = nil,
failure: ((NSData?) -> Void)? = nil
)
{ success?(NSData()) }
sendBody(success: { _ in print("ah, yeah!") })
También vale la pena señalar si está haciendo esto: si la persona que llama utiliza la sintaxis de cierre final, este será el último cierre en la lista de argumentos. Por lo tanto, desea que el último sea el que el usuario tenga más probabilidades de proporcionar, que probablemente sea el cierre exitoso:
func sendBody(
body: NSData? = nil,
success: ((NSData) -> Void)? = nil,
failure: ((NSData?) -> Void)? = nil
)
{
if success != nil { print("passed a success closure") }
if failure != nil { print("passed a failure closure") }
}
// this prints "passed a failure closure"
sendBody { data in
print("which closure is this?")
}
Aparte de esto, el orden en la declaración de función no le importa a quien llama, los argumentos predeterminados pueden proporcionarse en cualquier orden.