Reputation: 2925
I started learning Kotlin recently and I'd like to implement a simple postfix notation parser were instances of MathOperator
interface pick values from the stack and return the result.
The implementation is trivial in plain Java
public interface MathOperator {
public float evaluate(Deque<Float> stack);
public MathOperator ADD = stack -> stack.pop() + stack.pop();
public MathOperator SUB = stack -> -stack.pop() + stack.pop();
public MathOperator MUL = stack -> stack.pop() * stack.pop();
}
However, when I try the same in Kotlin I get "Property getter or setter expected" error.
interface KTMathOperator {
fun evaluate(stack: Deque<Float>): Float
companion object {
val ADD: KTMathOperator = (stack) -> stack.pop() + stack.pop()
}
}
How can I implement the same interface and its properties in Kotlin concisely?
Upvotes: 1
Views: 168
Reputation: 8422
Unfortunately, in Kotlin SAM conversions are not so handy. You can rewrite your example like:
interface KTMathOperator {
fun evaluate(stack: Deque<Float>): Float
companion object {
val ADD: KTMathOperator = object : KTMathOperator {
override fun evaluate(stack: Deque<Float>): Float = stack.pop() + stack.pop()
}
}
}
also you can change evaluate
to invoke
. Then you can your ADD
just like ADD(stack)
interface KTMathOperator {
operator fun invoke(stack: Deque<Float>): Float
companion object {
val ADD: KTMathOperator = object : KTMathOperator {
override fun invoke(stack: Deque<Float>): Float = stack.pop() + stack.pop()
}
}
}
fun main() {
val list = LinkedList<Float>().apply {
add(1.0f)
add(1.0f)
}
println(KTMathOperator.ADD(list)) // will print 2.0
}
If you're not too worried about maximum performance and a little strange code, you can also write like this :)
class KTMathOperator(private val operation: (Deque<Float>) -> Float) : (Deque<Float>) -> Float {
override fun invoke(stack: Deque<Float>): Float = operation(stack)
companion object {
val ADD: KTMathOperator = KTMathOperator { stack -> stack.pop() + stack.pop() }
}
}
Upvotes: 3