In an iOS app I have a popup button that contains a list of item names that can change.
I am trying to make a dictionary of [String : (String)->Void]
to store different actions to be performed based on the selected item.
The below function gives me the following error:
Cannot assign value of type '()' to subscript of type '(String) -> Void'
Isn't my closure of type (String)->Void
, or have I declared it incorrectly?
func selectOption(action : UIAction) {
var actionDict : [String : (String)->Void] = [:]
var assetNames : [String] = []
assetNames = assets.map { asset in
return asset.components(separatedBy: "@@@")[0]
}
var logAction = { (assetName: String) in
print(assetName)
}
assetNames.forEach { an in
actionDict[an] = logAction(an)
}
}
I have a big gap in my understanding.
If I change my declaration of actionDict to be ()
then the code compiles but it just executes the closure when I run it and it hits the line actionDict[an] = logAction(an)
, it just runs the closure rather than assigning it to the dictionary:
func selectOption(action : UIAction) {
var actionDict : [String : ()] = [:]
var assetNames : [String] = []
assetNames = assets.map { asset in
return asset.components(separatedBy: "@@@")[0]
}
var logAction : (String)->() = { (assetName: String)->() in
print(assetName)
}
assetNames.forEach { an in
actionDict[an] = logAction(an)
}
actionDict[action.title]
}
var assets: [String] = ["abc@@@XYZ", "mno@@@PQR@@@123", "xyz", "$#$#$"]
func selectOption(action : UIAction) {
var actionDict : [String : ((String)->())] = [:]
var assetNames : [String] = assets.map { $0.components(separatedBy: "@@@")[0] }
var logAction : ((String)->()) = { assetName in
print(assetName)
}
assetNames.forEach { an in
// only logAction(an) will triggle/call stored closure
// Instead of that, you can create new closure with parameter
actionDict[an] = { str in logAction(str) }
}
}
now it depends on when calling actionDict["abc"]("xyz")
.
what you expected?
"abc"
, then:Initialization:
var actionDict : [String : (()->())] = [:]
setup:
actionDict[an] = { logAction(an) }
call:
actionDict["abc"]()
"xyz"
, then:A dictionary with the same type of closure (with a String parameter) in every value is meaningless.
actionDict["print"]("xyz")
,actionDict["dump"]("abc")
actionDict["typecast"]("mno")
,actionDict["split"]("$#$#$")
So this third one is what you're looking for!