匿名接口实例作为Kotlin中的接口属性
我最近开始学习Kotlin,我想实现一个简单的解析器,它是匿名接口实例作为Kotlin中的接口属性,kotlin,lambda,Kotlin,Lambda,我最近开始学习Kotlin,我想实现一个简单的解析器,它是MathOperator接口的实例,从堆栈中选择值并返回结果。 在普通Java中,实现非常简单 公共接口运算符{ 公共浮动评估(Deque stack); 公共数学运算符ADD=stack->stack.pop()+stack.pop(); public MathOperator SUB=stack->-stack.pop()+stack.pop(); 公共数学运算符MUL=stack->stack.pop()*stack.pop();
MathOperator
接口的实例,从堆栈中选择值并返回结果。
在普通Java中,实现非常简单
公共接口运算符{
公共浮动评估(Deque stack);
公共数学运算符ADD=stack->stack.pop()+stack.pop();
public MathOperator SUB=stack->-stack.pop()+stack.pop();
公共数学运算符MUL=stack->stack.pop()*stack.pop();
}
然而,当我在Kotlin中尝试同样的方法时,我得到了“预期的属性getter或setter”错误
接口运算符{
乐趣评估(堆栈:Deque):浮动
伴星{
val ADD:KTMathOperator=(stack)->stack.pop()+stack.pop()
}
}
如何在Kotlin中简洁地实现相同的接口及其属性?不幸的是,在Kotlin中,SAM转换并不是那么方便。您可以将示例改写为:
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()
}
}
}
如果您不太担心最高性能和一些奇怪的代码,也可以这样编写:)
class-KTMathOperator(私有val操作:(Deque)->Float):(Deque)->Float{
重写调用(堆栈:Deque):Float=操作(堆栈)
伴星{
val ADD:ktmathmoperator=ktmathmoperator{stack->stack.pop()+stack.pop()}
}
}
SAM转换可以使代码更易于阅读。整个匿名概念并不方便,因为它有时会使代码变得混乱,而不是提高可读性。但这主要是因为Java实现lambdas的方式很笨拙(也就是说,使用了过多的命名接口,而这些接口大多是可以实现的)“纯”lambda有很多优点,而且简洁;例如,您永远不必从使用者转换为侦听器,因为它们是不同的接口,即使它们都是接受一个参数且不返回任何内容的函数。例如,这种情况可以在没有任何新接口的情况下完成,只需使用(Float)->Float
类型。
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()
}
}
}
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
}
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() }
}
}