Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
匿名接口实例作为Kotlin中的接口属性_Kotlin_Lambda - Fatal编程技术网

匿名接口实例作为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();

我最近开始学习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();
}
然而,当我在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() }
    }
}