@autoclosure
@autoclosure converts(wraps) expression inside function parameter in a closure[About]
Pros:
- easy to read
assert(2 == 5, "failed") - curly braces are not used
Cons
- hard to read. When you pass a function inside
@autoclosure it is not clear that this function will be deferred(because it is closure inside). fooWithAutoClosure(a: foo0()) - foo0() will be called not immediately as we expect reading this line
Overusing autoclosures can make your code hard to understand. The context and function name should make it clear that evaluation is being deferred.
Official doc
More examples
//functions block func foo0() -> String { return "foo0" } func foo1(i1: Int) -> String { return "foo1 " + String(i1) } func foo2(i1: Int, i2: Int) -> String { return "foo2 " + String(i1 + i2) }
//closures block func fooWithClosure0(p: () -> String) -> String { return "fooWithClosure0 " + p() } func fooWithClosure1(p: (Int) -> String) -> String { return "fooWithClosure1 " + p(1) } func fooWithClosure2(p: (Int, Int) -> String) -> String { return "fooWithClosure2 " + p(1, 2) }
//@autoclosure func fooWithAutoClosure(a: @autoclosure () -> String) -> String { return "fooWithAutoClosure " + a() }
//test closures func testClosures() { XCTAssertEqual("fooWithClosure0 foo0", fooWithClosure0(p: foo0)) XCTAssertEqual("fooWithClosure1 foo1 1", fooWithClosure1(p: foo1)) XCTAssertEqual("fooWithClosure2 foo2 3", fooWithClosure2(p: foo2)) XCTAssertEqual("fooWithClosure2 foo2 3", fooWithClosure2(p: { (i1, i2) -> String in return "fooWithClosure2 " + "foo2 " + String(i1 + i2) })) }
//test @autoclosure func testAutoClosures() { XCTAssertEqual("fooWithAutoClosure HelloWorld", fooWithAutoClosure(a: "HelloWorld")) //"HelloWorld" is String as returned value of @autoclosure XCTAssertEqual("fooWithAutoClosure foo0", fooWithAutoClosure(a: foo0())) XCTAssertEqual("fooWithAutoClosure foo1 1", fooWithAutoClosure(a: foo1(i1: 1))) XCTAssertEqual("fooWithAutoClosure foo2 3", fooWithAutoClosure(a: foo2(i1: 1, i2: 2))) }