String is not a subtype of () - ios

I was trying to create a block that I could enter parameters but had no return (a type block void). We know that the structure of a block that does not have parameters and not return anything is this:
var block: () -> () = {
//Hello World goes here
}
In the case of a block with parameters, but does not return anything, we can use this command:
var bloco7: (String) -> () = {
//Hello World goes here
}
But we have two problems: The first is that this code not working, the second is this code only works if we call a temporary variable like this:
var bloco7: (String) -> () = {
$0//I only need to call
//Hello World goes here and all the things OK
}
I wonder know why this is happening, it does not seem to make much sense ...

There's two parts here.
First, we declare the type of our closure:
var bloco7: (String) -> ()
bloco7 is a variable whose type is (String) -> () (a closure which takes a string and returns nil. We don't define the name of the parameter here. The parameter is named by the "closure literal syntax" so-to-speak.
So, if we want to have an inline closure, we can later to:
var bloco7: (String) -> () = {
yourArgument in // <-- here we named the parameter, it's called 'yourArgument'
println(yourArgument)
}
But it's important to note that we aren't defining the variable's name when we are declaring bloco7 and its type. Keep in mind that we can assign methods and functions to closure variables.
For example, given this function:
func sayHello(name: String) -> Void {
println("Hello, " + name + "!")
}
We can actually have bloco7 point to this function:
bloco7 = sayHello
And now, the following two lines actually do the exact same thing:
sayHello("World")
bloco7("World")
The important take-away here is that the argument names are irrelevant to the type of closure's type. The argument names are part of the value we assign to the variable, not part of its type.

In the first,you need to do it like tis
var bloco7: (String) -> () = {
input in
//Do something with input
}
bloco7 type is:(String)->()
{} type is :() -> ()
They do not match,so you get an error
But in the second way,you use $0,swift know that it has a input,it will match.Match $0 to the input String,so type is right

Related

Using closures as parameters without trailing closures Swift

When using trailing closure syntax it seems quite easy to pass a function as a parameter of another function.
However I want to do this WITHOUT using the trailing closure syntax
func doSomethingTwo(closure: (String) -> Void) {
closure("AAA")
}
doSomethingTwo(closure: print("TEST") )
gives
Cannot convert value of type '()' to expected argument type '(String) -> Void'
I know that
doSomethingTwo{ (test: String) in
print ("\(test)")
}
works, but want this without the trailing closure syntax.
This is not a homework problem, I am looking at tutorials and have done research that has not given me an answer to this question.
You need to define your own print method to pass it as a parameter:
func doSomethingTwo(closure: (String) -> ()) {
// when you call the closure you need to pass the string to be printed
closure("TEST")
}
Define the method to print the string that will be passed to the closure:
let closure: (String) -> () = { print($0) }
Then you can call it as you wish:
doSomethingTwo(closure: closure)
You're not calling the function correctly. You should call it like this:
doSomethingTwo(closure: { (text) in
print(text)
})
This is how you call a function
doSomethingTwo()
If we follow the pattern, put () first, then comes with its parameter, you'll get something like this.
doSomethingTwo(closure: { (str) in
print(str)
})
By the way, Xcode will helps you to complete. But if you don't want its help, when you have this, don't tap, type the rest by your own.
if you're getting this error you're probably missing an = sign
for e.g
yourClosure = { variable: VariableType in
print(variable)
}

How does one pass parameters to a function in Swift? Missing argument in call

Swift function parameters not accepted. Missing argument?
Calculate(theA, theB) //error: Missing argument label 'sideB:' in call
func Calculate(sideA: Int, sideB: Int) -> Int {
var ans = sideA + sideB
return ans;
}
You are missing the sideB: in your function call. I didn't want to rewrite your code (since you posted an image) but here's the working function call.
func calcButton(sender: AnyObject) {
let a: Int = 10
let b: Int = 11
calculate(a, sideB: b) //<-- Missing it here
}
func calculate(sideA: Int, sideB: Int) -> Int {
let a = sideA + sideB
return a
}
you might also want to have both variables in the function call so you can do this instead:
func calcButton(sender: AnyObject) {
let a: Int = 10
let b: Int = 11
calculate(sideA: a, sideB: b)
}
func calculate(sideA A: Int, sideB B: Int) -> Int {
return A + B
}
Just an FYI, use tab completion instead of writing out the function. Xcode will let you know all the function variables with placeholders so you can type them in.
you have missed the sideB param name in swift 3 first parameter is optional but second param is Mandatory that _ in there That’s an underscore. It changes the way the method is called. To illustrate this, here’s a very simple function:
func doStuff(thing: String) {
// do stuff with "thing"
}
It’s empty, because its contents don’t matter. Instead, let’s focus on how it’s called. Right now, it’s called like this:
doStuff(thing: "Hello")
You need to write the name of the thing parameter when you call the doStuff() function. This is a feature of Swift, and helps make your code easier to read. Sometimes, though, it doesn’t really make sense to have a name for the first parameter, usually because it’s built into the method name.
When that happens, you use the underscore character like this:
func doStuff(_ thing: String) {
// do stuff with "thing"
}
That means “when I call this function I don’t want to write thing, but inside the function I want to use thing to refer to the value that was passed in.

Closures In Swift?

I am new to iOS coding and I am stuck in closures feature of SWIFT. I have referred to many tutorials and found that closures are self written codes which can be used in many ways eg. as arguments in function call,parameters in function definition,variables. I am giving below an example below with my associated thoughts about the code & questions. Please help me if I am wrong in my understanding. I know I am wrong at many points,so please rectify me.
1.1st Part
func TEST(text1:String,text2:String,flag: (S1:String,S2:String)->Bool)//In this line,I think,I am using flag is a closure which is passed as parameter in a function. And if so why doesn't it follow the standard closure syntax?
{
if flag(S1: text1, S2: text2) == true//I want to check the return type what flag closure gets when it compares the both string during function call. Why can't I write as if flag == true as flag is the name of the closure and ultimately refers to the return type of the closure?
{
print("they are equal")
}
else
{
//
}
}
2nd Part
This part is the most troublesome part that really confuses me when I am calling the function. Here I am also using the same closure. What is happening over here? How is the closure being used? Is it capturing values or something else?
TEST("heyy", text2: "heyy") { (S1, S2) -> Bool in
S1==S2
}
Thanks for your kind consideration.
Your closure usage is ok. A closure is some code that can be passed to be executed somewhere else. In your case you can choose to pass the real test you want to the function TEST, simple string test or case-insensitive test, etc. This is one of the first usage of closure: obtain more genericity.
And yes closures capture something, it captures some part of the environnement, i.e. the context in which they are defined. Look:
var m = "foo"
func test(text1:String, text2:String, testtFunc: (s1:String, s2:String) -> Bool) {
m = "bar"
if testFunc(s1: text1, s2: text2) { print("the test is true") }
}
m = "baz"
test("heyy", text2: "heyy") { (s1, s2) -> Bool in
Swift.print("Value for m is \(m)")
return s1==s2
}
The closure captures m (a variable that is defined in the context in which you define the closure), this means that this will print bar because at the time the closure is executed, the captured m equals to bar. Comment bar-line and baz will be printed; comment baz-line and foo will be printed. The closure captures m, not its value, m by itself, and this is evaluated to the correct value when the closure is evaluated.
Your first function works like this :
arguments :
String 1
String 2
a function that takes two Strings as arguments and returns a Bool
body :
execute the function (flag) with text1 and text2 and check the result.
The function doesn't know at all what you are testing, it only knows that two pieces of text are needed and a Bool will be returned.
So this function allows you to create a general way of handling different functions that all have two Strings as input. You can check for equality or if the first pieces of text is a part of the second and so on.
This is useful for many things and not so far from how array filtering / sorting / map works.
2nd Part :
This is just how you call a function with a closure.
TEST("heyy", text2: "heyy") { (S1, S2) -> Bool in
S1 == S2
}
You can also call it like this :
func testStringEqualityFor(text:String, and:String) -> Bool {
return text == and
}
TEST("hey", text2: "hey", flag: testStringEqualityFor)
Instead of using the trailing closure syntax to pass an unnamed function, you now pass a named function as one of the arguments.
It al becomes a lot clearer when you simplify it.
This is a function that takes another function as an argument.
Now we can call/use this function inside it. The argument function takes a bool as it's argument. So we give it a true
func simpleFunctionWithClosure(closure:(success:Bool) -> Void) {
// use the closure
closure(success: true)
}
When we use the function we need to pass it a function. In Swift you have the trailing closure syntax for that, but that is only available (and even then optional) to the first function as argument.
Trailing closure syntax means that instead of passing a named function you can write:
myFunction { arguments-for-closure-as-tuple -> return-for-closure-as-tuple in
function-body
}
The closure will receive an argument of Bool and returns nothing so Void.
In the body we can handle the arguments and do stuff with them.
But it is important to remember that what is inside the closure is not called directly. It is a function declaration that will be executed by simpleFunctionWithClosure
// use the function
simpleFunctionWithClosure { (success) -> Void in
if success {
print("Yeah")
} else {
print("Ow")
}
}
Or with a named function :
func argumentFunction(success:Bool) -> Void {
if success {
print("Yeah")
} else {
print("Ow")
}
}
simpleFunctionWithClosure(argumentFunction)
Compiler wouldn't have any expectation how your closure is for. For example in your first case, it could not estimate the closure's intake parameters is always just reflect to the first and second parameters of the TEST function when we are always able to write the following code :
func Test(str1:String,str2:String,closure:(String,String)->Bool){
if closure(str[str1.startIndex...str1.startIndex.advanced(2)],str2[str2.startIndex.advanced(1)...str2.endIndex])
{ ... }else{ ... }
//Just an example, everybody know no one write their code like this.
}
The second case, I thought you've just overlooked the syntax sugar:
For a trailing closure A->B:
{ a:A -> B in a.bValue() }
is equal to :
{ a:A -> B in return a.bValue() }
Also, I think this TEST function isn't a good example when the task of it can be done without using closure. I think you can write a map function by yourself for a better understand of why and when to use closure.

Swift Closure why does calling function return error?

just learning about closures and nesting functions. Given the nested function below:
func printerFunction() -> (Int) -> () {
var runningTotal = 0
func printInteger(number: Int) {
runningTotal += 10
println("The running total is: \(runningTotal)")
}
return printInteger
}
Why does calling the func itself have an error, but when I assign the func to a constant have no error? Where is printAndReturnIntegerFunc(2) passing the 2 Int as a parameter to have a return value?
printerFunction(2) // error
let printAndReturnIntegerFunc = printerFunction()
printAndReturnIntegerFunc(2) // no error. where is this 2 going??
First of all you are getting error here printerFunction(2) because printerFunction can not take any argument and If you want to give an argument then you can do it like:
func printerFunction(abc: Int) -> (Int) -> (){
}
And this will work fine:
printerFunction(2)
After that you are giving reference of that function to another variable like this:
let printAndReturnIntegerFunc = printerFunction()
which means the type of printAndReturnIntegerFunc is like this:
that means It accept one Int and it will return void so this will work:
printAndReturnIntegerFunc(2)
(1) The function signature of printerFunction is () -> (Int) -> () which means it takes no parameter and returns another function, thats why when you try to call printerFunction(2) with a parameter gives you an Error.
(2) And the signature of the returned function is (Int) -> () which means it takes one parameter of Int and returns Void. So printAndReturnIntegerFunc(2) works

Swift inferred closure parameter puzzle

As a homage to Ruby I've been playing with an extension to Int that allows me to write useful code like this:
3.times { println("I keep holding on") }
This works well and here's the extension:
extension Int {
func times(fn: () -> ()) {
for i in 1...self {
fn()
}
}
}
Now, I'd like to pass the iteration number in to the closure, so I added a 2nd times() function to extension:
extension Int {
func times(fn: (iteration: Int) -> ()) {
for i in 1...self {
fn(iteration: i)
}
}
}
Which can be invoked like this:
5.times { (i: Int) -> () in println("Year \(i)") }
Now, according to the Swift docs,
It is always possible to infer the parameter types and return type
when passing a closure to a function as an inline closure expression.
As a result, you never need to write an inline closure in its fullest
form when the closure is used a function argument.
That sounds great, because then I can omit the parameter and return types, i.e. (i: Int) -> (), and just use the following syntax instead:
5.times { i in println("Year \(i)") }
But this leads to the following error: Error: Ambiguous use of 'times'
Is this way of invoking my times() function really ambigous to the compiler?
It is ambiguous. Both .times() methods can be used with the given closure expression if the parameter type of the closure is not known.
If you just write { i in println("Year \(i)") }, it is just a closure that takes one parameter of any type. Well, EVERY function type in Swift can be viewed as taking one parameter:
What you think of as zero-parameter functions actually take one parameter of type () (a.k.a. Void), of value (), that's why the type is written as () -> something
What you think of as multiple-parameter functions actually take one parameter of tuple type, a tuple of all the "multiple arguments", that's why the type is written as (foo, bar) -> something.
So, basically, your closure expression, without specifying the type of i, can be inferred to ANY function type in Swift that returns Void. The functions taken by both .times() methods match this -- for the first .times() method, it is inferred as a function of type () -> (), i.e. i has type (); for the second .times() method, it is inferred as a function of type Int -> (), i.e. i has type Int.
it looks like the ambiguity derives from the 2 extension methods having the same name. If you comment your first version of the times function, it works fine - if you comment the 2nd instead, surprisingly, you do not get an error from the compiler.
There is no ambiguity in my opinion, because the 2 functions have different signature - () -> () is different than (iteration: Int) -> (). I think it's a bug in the compiler, specifically type inference is failing.
Making the call explicit instead it works fine
5.times { (i: Int) -> () in println("Year \(i)") }
If the first version with the parameterless closure is commented, the line above compiles correctly, if instead the 2nd overload is commented, compilation fails as expected.
To prove that something is wrong in the compiler, this seems to work, whereas I'd expect a compilation error instead:
extension Int {
func times(fn: () -> ()) {
for i in 1...self {
fn()
}
}
}
5.times { i in println("Year \(i)") }
This is the output from the playground console:
Year ()
Year ()
Year ()
Year ()
Year ()

Resources