问题
Question: What are the basic rules and boundaries (in terms of syntax) that need to be considered when writing any closure in swift?
回答1:
Closure Rules:
If the closure block solely returns value after the 'in' keyword (or the closure block just returns a value) then using 'return' keyword is optional.
Defining closure argument type is optional if the closure type is explicitly defined.
Defining closure return type is optional, if closure arguments are defined with it's type and there is no other statement in the return block or the closure type is explicitly defined.
Defining closure arguments, return type and 'in' keyword is optional if closure is explicitly defined, in this case if the closure has any argument, it is compulsory to use them and refer them using indexes, eg: $0 represents first argument, $1 represents second argument and so on.
Defining closure type, arguments, return type and 'in' keyword is optional if closure have no arguments and there is no other statement in the return block.
Defining closure type explicitly is optional if closure arguments(if any) are defined with it's type and either there is no other statement in the return block or return type is also defined.
If type is defined explicitly then it should be defined completely.
Closure rules in action:
// Rule#1: If the closure block solely returns value after the 'in' keyword (or the closure block just returns a value) then using 'return' keyword is optional.
var rule_1:(String)->String = { (txt:String)->String in
"Rule_1: 'return' keyword is not defined because there is no other statement in the return block, Text = \(txt)"
}
print(rule_1("xyz"))
print("")
// Rule#2: Defining closure argument type is optional if the closure type is explicitly defined.
var rule_2:(String)->String = { (txt)->String in
print("", terminator:"")
return "Rule_2: Closure argument type is not defined because closure type is explicitly defined, Text = \(txt)"
}
print(rule_2("xyz"))
print("")
// Rule#3: Defining closure return type is optional, if closure arguments are defined with it's type and there is no other statement in the return block or the closure type is explicitly defined.
var rule_3_1:(String)->String = { (txt:String) in
print("", terminator:"")
return "Rule_3_1: Return type is not defined because closure type is explicitly defined, Text = \(txt)"
}
var rule_3_2 = { (txt:String) in
return "Rule_3_2: Return type not defined because arguments are defined with it's type and there is no other statement in the return block, Text = \(txt)"
}
print(rule_3_1("xyz"))
print(rule_3_2("xyz"))
print("")
// Rule#4: Defining closure arguments, return type and 'in' keyword is optional if closure is explicitly defined, in this case if the closure has any argument, it is compulsory to use them and refer them using indexes, eg: $0 represents first argument, $1 represents second argument and so on.
var rule_4:(String)->String = {
print("", terminator:"")
return "Rule_4: Closure arguments, return type and 'in' keyword is not defined because closure is explicitly defined, Text = \($0)"
}
print(rule_4("xyz"))
print("")
// Rule#5: Defining closure type(explicitly), arguments, return type and 'in' keyword is optional if closure have no arguments and there is no other statement in the return block.
var rule_5 = {
return "Rule_5: Closure type, closure arguments, return type and 'in' keyword not defined because closure have no arguments and there is no other statement in the return block, Text = \"\""
}
print(rule_5())
print("")
// Rule#6: Defining closure type explicitly is optional if closure arguments(if any) are defined with it's type and either there is no other statement in the return block or return type is also defined.
var rule_6_1 = { (txt:String)->String in
print("", terminator:"")
return "Rule_6_1: Closure not explicitly defined because closure arguments are defined with it's type and return type, Text = \(txt)"
}
var rule_6_2 = { (txt:String) in
return "Rule_6_2: Closure not explicitly defined because closure arguments are defined with it's type and there is no other statement in the return block, Text = \(txt)"
}
print(rule_6_1("xyz"))
print(rule_6_2("xyz"))
Output:
回答2:
There are multiple types of closure, we can use closure wih void return , single param return and multiple return type,
we can use inout , typealaise , escaping , autoclosure
key words and that functionality in closure.
actually closure is the self containing block with params and returntype
here i added code for closures
class ClouserVC : UIViewController{
var clouserPrint = {
print("Clouser just print value")
}
var closureInoutData = { ( value : inout String) in
value = "Value Changed"
}
typealias colsureTypealaise = ((String) -> Void)
var valueforInout = "initail value"
var valueforClosureInout = "Clouser Value"
override func viewDidLoad() {
super.viewDidLoad()
self.clouserPrint()
self.closureWithFun {
print("==>This from closureWithFun , but it pass empty data")
}
print("=!=> Value before inout Closure" , valueforInout)
self.closureInoutData(&valueforInout)
print("=!=> Value after inout Closure" , valueforInout)
self.closureWithValidFun { (argument) -> String in
print("===> getting passed value from closure \(argument)")
return ""
}
self.closureWithTypeAlise { (typeAlasie) in
print("====> This value declared in Typealasie , \(typeAlasie)")
}
self.closureWithMultipleParams { (strValue, intValuse) -> (String) in
print("=====> get mupltiple datas from function , \(strValue) , \(intValuse.description)")
return strValue
}
let closureReturns = self.funcWithClouserReturn(argument: 10)
self.funcwithEscapingClosure { (escaping) in
print("=======> get escaping closure values === \(escaping)")
}
print("=8=> Value before inout FunClosure" , valueforClosureInout)
self.funcWithClosureInOutParam { (inoutData) in
print("=*8=>",inoutData )
inoutData = "valueChangefor InoutClosure"
}
print("=8=> Value after inout FunClosure ===" , valueforClosureInout)
}
func closureWithFun(argument : ()-> Void){
print("==>Function with argument closure , but it passes empty data")
}
func closureWithValidFun(argument : (String) -> String){
print("===> Function have valid argument")
argument("value_passed_from_by_this_type")
}
func closureWithTypeAlise(argumenttype :colsureTypealaise){
print("====> Function have Typealaised params")
argumenttype("Hello Alaise")
}
func closureWithMultipleParams(multiple params : (String,Int) -> (String)){
print("=====> Here we pass multiple params to returnback to its function call" )
params("Multiple",2)
}
func funcWithClouserReturn(argument params : Int) -> () ->(String){
print("======> Closure returns from the function")
func closuserInfunc() -> String{
return "closure value inside the func \(params)"
}
return closuserInfunc
}
func funcwithEscapingClosure(argument Param: @escaping(String)->()){
print("=======> This func have Excaping closure as a param")
Param("Hello")
}
func funcWithClosureInOutParam(argument param : (inout String) -> ()){
print("=8=> This func have inout argument")
param(&valueforClosureInout)
}
}
来源:https://stackoverflow.com/questions/59332092/how-many-ways-there-to-write-a-closure-in-swift