Swift map on UILabel Anonymous closure argument not contained in closure
This code is invalid because it's using an anonymous closure argument $0
, without being in a closure.
[nameLabel, numberLabel, informationLabel].map(contentView.addSubview($0))
There are two ways to fix this, either put it in a closure:
[nameLabel, numberLabel, informationLabel].map { contentView.addSubview($0) }
Or better yet, just use the instance method directly:
[nameLabel, numberLabel, informationLabel].map(contentView.addSubview)
In either case, you should use forEach
rather than map
, since you don't care about the (Void
) return value of addSubview
:
[nameLabel, numberLabel, informationLabel].forEach(contentView.addSubview)
(lldb) error: anonymous closure argument not contained in a closure
The "p" command actually compiles the text you type as though the expression had been in the text of the frame you are stopped in. To do that it has to completely recreate that context. lldb gets a lot of this right, but it doesn't yet know how emulate the $ closure automatic variables in the context it uses to compile expressions.
But more generally, the job print
tries to do is a much harder task that just viewing local variables, and not surprisingly lldb also has a more straightforward way to view simple local variables. That facility is what Xcode uses to implement the locals view and the tooltips. But it is also an lldb command-line command:
(lldb) frame var $0
The "frame var" command doesn't have a full language parser, for instance it can't evaluate expressions. But it does allow you to specify elements of a struct, for instance:
(lldb) frame var $0.delegate
You might have more luck with the frame var
command.
how to call a closure with argument in a function
That is not how closures work in Swift. And the code you wrote doesn't even make sense. Why do you assign n
to name
then change the value of name
just to print it ?
The function with the closure will call the closure with a given value. You can think of closures as lambda functions. Here is an example:
func test(_ closure: @escaping (String) -> Void) {
closure("My string")
}
test { str in
print(str) //prints " My string"
}
For what you are trying to achieve, just use a String parameter in your function:
func test(_ str: String) {
print(str)
}
test("My string") // prints "My string"
Or use a closure that takes Void:
func test(_ closure: @escaping (Void) -> Void) {
closure()
}
test {
print("My string") // prints "My string"
}
Anonymous closure can not be used inside a closure that has explicit arguments
There are two ways to write closures: with explicit argument names, or by referring to the arguments as $0, $1 etc.
For example, these two things are equivalent:
// implicit argument names, $0 and $1
let x = reduce(1...5, 0) { $0 + $1 }
// explicit argument names i and j
let y = reduce(1...5, 0) { i, j in i + j }
But you can’t mix these things – either you name the arguments, or you use $n
. You can’t do both:
// name the arguments, but still use $0 and $1
let x = reduce(1...5, 0) { $0 + $1 }
// compiler error: Anonymous closure arguments cannot be used
// inside a closure that has explicit arguments
In your example, it looks like you’ve forgotten to supply a closure to the filter
method. This means your $0
isn’t inside a new closure without arguments – so the Swift compiler thinks your $0
is referring to the outer closure that names it’s arguments explicitly as records
and error
. So it’s complaining you can’t refer to arguments as $0
inside a closure with explicit argument names.
(the fix is of course to actually supply a closure to filter
i.e. replace your ()
with {}
)
Print (po) the value of a Swift anonymous closure argument from the console in Xcode
This is a known issue with Xcode 8.1 GM Seed. From the release notes:
Anonymous closure arguments in Swift cannot be used in LLDB expressions. For example,
po $0
is not supported.
You can use the frame variable command to print its value:
fr va $0
This issue is filed as rdar://28611943
.
Accessing only a subset of anonymous closure arguments
To the compiler, it looks like your closure is only handling a single float parameter, because your closure never references the other 5 "things" in any way. So there is an apparent mismatch and the compiler flags it as an error.
If you reference all 6 input parameters in any valid way, the error will disappear. For example, although this is not something you should ever write, merely referencing the additional parameters like this will be valid:
self.someClosure = { self.handleThing0($0); _ = [$1,$2,$3,$4,$5] }
The shortest / best possible way to express what you are going for is:
self.someClosure = { thing0, _, _, _, _, _ in self.handleThing0(thing0) }
where each _
represents a value you are ignoring, but the compiler can infer that they would be Float values.
Related Topics
How to Test If Objects Conforming to the Same Protocol Are Identical in Swift Without Casting
Parse.Com Querying User Class (Swift)
Why I Can Change/Reassigned a Constant Value That Instantiated from a Class
Unexpectedly Large Realm File Size
Why Can't I Use a Tuple Constant as a Case in a Switch Statement
Converting a C-Style for Loop That Uses Division for the Step to Swift 3
Know When an Iteration Over Array with Async Method Is Finished
Is This a Good Way to Display Asynchronous Data
How to Write a Function That Will Unwrap a Generic Property in Swift Assuming It Is an Optional Type
Parameters After Opening Bracket
How to Convert Between Related Types Through a Common Initializer
Swiftier Swift for 'Add to Array, or Create If Not There...'
Swift Dictionary: Remove Time Complexity
Scene Size in Xcode 6/Spritekit/Swift