Happy Friday all. I'm having trouble with a `opera...
# announcements
t
Happy Friday all. I'm having trouble with a
operator fun invoke
that takes a
vararg
. Here's my stripped-down sample code, the trouble is with the syntax
{ fn }
in
main
, it says "Too many arguments for public constructor NamesBuilder() defined in NamesBuilder". :
Copy code
class NamesBuilder {
    private val names:MutableList<String> = ArrayList()
    
    fun build(): List<String> = names.toList()

    operator fun invoke(vararg data: () -> String): NamesBuilder = this.apply { data.forEach { names.add(it()) } }

    companion object Helper {
        operator fun invoke(vararg data: () -> String): List<String> = NamesBuilder()(*data).build()
    }
}

fun main() {
    val fn: () -> String = { "1" }
    println(NamesBuilder {fn}) // does not work -- Too many arguments...
    println(NamesBuilder.invoke(fn)) // works fine, prints [1]
}
As I understand it, the
{ fn }
syntax should invoke the companion operator fun invoke function... and this works fine if I use
.invoke(fn)
. I've tried numerous variations on this theme but no joy. Can someone help me make this work?
s
The compiler seems to have issues omitting the open
(
and close
)
for the last argument with a vararg lambda. However, these work fine:
Copy code
println(NamesBuilder({ fn() }))
    println(NamesBuilder(fn))
t
while i think the error message is wrong or misleading at least. you code is wrong, too. in fact you are passing an argument of type
() -> () -> String
s
@thana Even after
NamesBuilder {fn}
is fixed to
NamesBuilder {fn()}
, the error message is still shown. It seems to be an issue with omitting the round open and close brackets. Not sure if this is a ‘bug’ or not for the compiler…
t
agreed
t
Thanks for the quick replies! So yeah, it doesn't matter what I put in the curly brackets`{}`, the same error is shown. (Including leaving it blank.) As you noted Anton, the
NamesBuilder({ fn() }))
syntax works. IntelliJ suggests that I pull the lambda out of the parentheses, so it seems like this ought to work.
s
I agree. It either should work or it shouldn’t suggest to pull the lambda outside the parentheses.
c
Yeah, I think this belongs on https://kotl.in/issue
k
I reported this similar inspection issue about two years ago: https://youtrack.jetbrains.com/issue/KT-20531
Looks like that inspection is a bit too greedy in general simple smile
t
Using the issue Karel reports, I can create the following code:
Copy code
fun baz(vararg a: () -> Unit) {
    a.forEach { it() }
}

fun xy() { }

fun test() {
    baz({xy()})
    baz { xy() }
}
The first call to
baz
works; the second fails with "Passing value as a vararg is only allowed inside a parenthesized argument list" So that error seems to suggest the real limitation, and the compiler/IDE are providing a misleading error (Too many arguments...) and invalid hint to remove the parentheses.
👍 3