Compiler doesn't consider 'companion invoke' as construction alternative


#1

Here is the sample that tries to construct an object from a lambda using companion invoke operator:

class Something<T>(val value: T) {
	companion object {
		operator inline fun <T> invoke(code: () -> T):Something<T> = Something(code())
	}
}

fun test():Something<Int> = Something { 0 } //Expected: Something<Int>. Found: Something<() -> Int>

And here is the compiler’s complaint on the fun test:

Expected: Something<Int>. Found: Something<() -> Int>

That is the compiler apparently ignores companion invoke and tries to use the class constructor.

Of course it’s possible to add another constructor(code: () -> T) which neglects the advantage of inlining. Or remove the constructor and replace it with companion invoke(value: T) which adds a call stack.

So why not ask the compiler to consider companion invoke operators when it chooses the way of object construction?


#2

Why not use a free function with the name of the class instead? It has the same effect and the advantage that it doesn’t need a companion instance.


#3

Looks a bit tricky when called from Java code, but really nice option after all. Thanks.
And now compiler behavior appears even more weird. It accounts top-level function but ignores companion’s one.


#4

Compiler needs a little help inferring the types, try this:

fun test(): Something<Int> = Something<Int> { 0 }

#5

Yep. Correct. But unlikely you’d enjoy using such cluttered function from someone’s library.