1

Let's say I have a class like:

class Testing() {
    var var1 = 0
    var str1 = ""
    var b = false

    fun test(var1: Int, str1: String, lambda1: (Boolean)->Unit){
    this.var1 = var1 
    this.str1 = str1 
    // do something
    }
}

How to call the method test and pass boolean to run lambda body?

var t1 = Testing()
t1.test(1, "String"){
      // do something else
}
7
  • 1
    you showed how to call the test-function with your t2-assignment. In the test-implementation you may want to call lambda1(yourBoolean) (or lambda1.invoke(yourBoolean))... how you get that boolean is up to you... in the call of test you have the boolean available in the part where you wrote // do another thing using it ... you can also name that parameter if you wish, e.g. yourBool -> println("do something with your $yourBool") Commented Jul 8, 2019 at 11:40
  • I've edited my question, but still don't understand how to pass the boolean. When I try to call test(1, "String", true) I get an error: to many arguments... Commented Jul 8, 2019 at 12:40
  • You're error will not be too many arguments, it will be "The boolean literal does not conform to the expected type ((Boolean) -> Unit)" Commented Jul 8, 2019 at 12:51
  • the third parameter of test is a function itself... you can't just pass the boolean value. The boolean value is supposed to be delivered from within the test-function... at least that is, what I get from that signature ;-) Commented Jul 8, 2019 at 12:53
  • 1
    and when you call test from outside, you have to use the callback function to decide what will happen with that given boolean value... Commented Jul 8, 2019 at 12:54

2 Answers 2

3

You need to name your lambda parameter, or, if it's not to be used, name it as _.

Like so:

fun example1() {
    var t1 = Testing()
    t1.test(1, "String") { bool ->
        // Do stuff
    }
}

fun example2() {
    var t1 = Testing()
    t1.test(1, "String", { bool -> 
        // Do stuff
    })
}

I presume you want to invoke your callback in the test method in Testing class. In which case you need to provide the argument to the function in order to invoke the lambda with the arg. can do it like this:

class Testing() {
    var var1 = 0
    var str1 = ""
    var b = false

    fun test(var1: Int, str1: String, lambdaArg: Boolean, lambda1: (Boolean)->Unit){
        this.var1 = var1
        this.str1 = str1
        // Invoke the callback
        lambda1(lambdaArg)
    }
}

Or, if the arg to be passed to the lambda is a function of what happens in your test function, then you can ommit providing the lambda arg to test and instead hardcode your arg in the call to the lambda like this:

class Testing() {
    var var1 = 0
    var str1 = ""
    var b = false

    fun test(var1: Int, str1: String, lambda1: (Boolean)->Unit){
        this.var1 = var1
        this.str1 = str1
        if (this.var1 == 0) {
            lambda1(false)
        } else { 
            lambda1(true)
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Sure, I tend to avoid using it and prefer to name my lambda params, because as soon as you have nested lambdas it becomes confusing which it you are referring to.
I think your 2nd snippet is confusing and based on a wrong presumption. Why would you (or anyone) pass lambda1 and then also pass the arg that the lambda will use?
Because lambda1 is a function pointer and has no idea what value will be passed to it. If you provide { x -> launchMissiles(x) } in one instance and { x -> makeWorldPeace(x) } in another that's quite a different thing.
Ok, it is a bit confusing. My example in the 3rd snippet clarifies the case where you don't want to pass the argument for the lambda into the function as the argument is based on what happens in the function (rather than provided from external source).
2
class Testing() {
  var var1 = 0
  var str1 = ""
  var b = false

  fun test(var1: Int, str1: String, lambda1: (Boolean)->Unit){
    this.var1 = var1 
    this.str1 = str1 
    // do something
    lambda1(false) // or lambda1.invoke(true) // here your boolean value is passed to your lambda1-function
  }
}

Somewhere else:

test(1, "one") {
  // this is now your lambda1-function-body accepting a boolean...
  // here you now have three(+) ways to implement it...
}

Variants of the lambda1-body:

  1. ignoring the given boolean value:

    test(1, "one") { // _ -> // <- you can write this out explicitly if you like
      println("boolean value is ignored here")
    }
    
  2. using it or a named parameter (in this case passedBool):

    test(1, "one") { passedBool ->
      println("boolean value $passedBool was passed")
    }
    
  3. method reference:

    fun anythingThatConsumesABoolean(bool : Boolean) { }
    
    test(1, "one", ::anythingThatConsumesABoolean)
    

So as you can see: you do not pass the boolean value from outside, but rather deal with it in the callback function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.