4

Which of the following is better:

Sample1:

var x: Int = 0
for _ in 1...5 {
    someList.append( Foobar(someClosure: { println("X = \(x)") }))
}

Sample2:

var x: Int = 0
var c: ()->() = { println("X = \(x)") }
for _ in 1...5 {
    someList.append( Foobar(someClosure: c))
}
  • If I think of closures as reference types, then sample2 would be best since I'm reusing the same object (reduce memory allocation, reuse objects).
  • If I think of closures as value types, then it really doesn't matter. I would have to trust the compiler to recognized that the closures are the same and that it knows to use the same closure (similarly to what would happen if I used the same literal string within my code in multiple locations). Choosing one over the other would be considered "premature optimization".

Edit:

Is there a fundamental difference between both samples (aside from writing style)?

  • Better for what? This isn't any different from asking about creating an `Int` variable or using the literal value when you call an argument. In the first example, arguably, you're using a "closure literal", where in the second, you're using a closure variable. – nhgrif May 25 '15 at 19:15
  • @nhgrif Then I guess I'm asking if there's such a thing as a "closure literal".. in my mind, it's not obvious if they do or not. Does it actually make a difference for closures? –  May 25 '15 at 19:18

1 Answers1

6

You're misusing the word "closure". All functions are closures in Swift. So you just mean "function".

A function can have a name. The way you show is one way to give a function a name:

var c: ()->() = { println("X = \(x)") }

But here's another way:

func c() {
    println("X = \(x)")
}

That's right. Declaring a function is just a way of giving a function a name.

However, a function can also be anonymous, meaning it has no name. That's just a way of making the code shorter when no name is needed, because the function body can be defined inline in the one place where it is used. You show an example of that too:

for _ in 1...5 {
    someList.append( Foobar(someClosure: { println("X = \(x)") }))
}

So give a function a name if you want to or need to, and don't if you don't. There's no advantage, disadvantage, or difference one way or the other.

Except for one thing: an anonymous function can have a capture list (defining the memory management of class instances captured from outside the function body, e.g. [weak self] in), but a declared function cannot. I regard that as a bug in the language, though not a very serious one.

matt
  • 515,959
  • 87
  • 875
  • 1,141